From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/kernel32/tests/debugger.c | 7 ++++++- dlls/ntdll/unix/sync.c | 27 +++++++++++++++++++++++++++ include/wine/server_protocol.h | 4 +++- server/debugger.c | 25 +++++++++++++++++++++++++ server/mapping.c | 3 --- server/protocol.def | 2 ++ server/request.h | 4 +++- server/trace.c | 1 + 8 files changed, 67 insertions(+), 6 deletions(-)
diff --git a/dlls/kernel32/tests/debugger.c b/dlls/kernel32/tests/debugger.c index f27db2872d1..4879a729169 100644 --- a/dlls/kernel32/tests/debugger.c +++ b/dlls/kernel32/tests/debugger.c @@ -1157,11 +1157,16 @@ static void test_debug_loop_wow64(void) ret = CloseHandle(pi.hProcess); ok(ret, "CloseHandle failed, last error %#lx.\n", GetLastError());
- todo_wine + if (strcmp(winetest_platform, "wine") || num_wow64) /* windows or new wine wow */ { ok(num_ntdll == 2, "Expecting two ntdll instances\n"); ok(num_wow64 >= 3, "Expecting more than 3 wow64*.dll\n"); } + else /* Wine's old wow, or 32/64 bit only configurations */ + { + ok(num_ntdll == 1, "Expecting 1 ntdll instances\n"); + ok(num_wow64 == 0, "Expecting 0 wow64*.dll\n"); + } ok(bp_order, "Expecting 1 bp exceptions\n"); todo_wine { diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c index 22a3555ba3f..cfcac3735f2 100644 --- a/dlls/ntdll/unix/sync.c +++ b/dlls/ntdll/unix/sync.c @@ -1017,6 +1017,26 @@ static NTSTATUS event_data_to_state_change( const debug_event_t *data, DBGUI_WAI return STATUS_INTERNAL_ERROR; }
+/* Don't expose 64bit load/unload dll event for a 32bit caller; helper for NtWaitForDebugEvent */ +static BOOL filter_out_event( HANDLE handle, DBGUI_WAIT_STATE_CHANGE *state, USHORT machine ) +{ + switch (state->NewState) + { + case DbgLoadDllStateChange: + case DbgUnloadDllStateChange: + if (NtCurrentTeb()->WowTebOffset && is_machine_64bit( machine )) + { + if (state->NewState == DbgLoadDllStateChange) + NtClose( state->StateInfo.LoadDll.FileHandle ); + NtDebugContinue( handle, &state->AppClientId, DBG_CONTINUE ); + return TRUE; + } + break; + default: break; + } + return FALSE; +} + /********************************************************************** * NtWaitForDebugEvent (NTDLL.@) */ @@ -1026,6 +1046,7 @@ NTSTATUS WINAPI NtWaitForDebugEvent( HANDLE handle, BOOLEAN alertable, LARGE_INT debug_event_t data; unsigned int ret; BOOL wait = TRUE; + unsigned int machine;
for (;;) { @@ -1039,10 +1060,16 @@ NTSTATUS WINAPI NtWaitForDebugEvent( HANDLE handle, BOOLEAN alertable, LARGE_INT state->NewState = data.code; state->AppClientId.UniqueProcess = ULongToHandle( reply->pid ); state->AppClientId.UniqueThread = ULongToHandle( reply->tid ); + machine = reply->machine; } } SERVER_END_REQ;
+ if (!ret && filter_out_event( handle, state, machine )) + { + wait = TRUE; + continue; + } if (ret != STATUS_PENDING) return ret; if (!wait) return STATUS_TIMEOUT; wait = FALSE; diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index f61918271ff..f3af2f4636d 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -2117,6 +2117,8 @@ struct wait_debug_event_reply struct reply_header __header; process_id_t pid; thread_id_t tid; + unsigned int machine; + int __pad; /* VARARG(event,debug_event); */ };
@@ -6358,7 +6360,7 @@ union generic_reply
/* ### protocol_version begin ### */
-#define SERVER_PROTOCOL_VERSION 762 +#define SERVER_PROTOCOL_VERSION 763
/* ### protocol_version end ### */
diff --git a/server/debugger.c b/server/debugger.c index 48adb244b09..6d0942f5770 100644 --- a/server/debugger.c +++ b/server/debugger.c @@ -531,6 +531,30 @@ void debugger_detach( struct process *process, struct debug_obj *debug_obj ) resume_process( process ); }
+static unsigned int get_machine_from_event( struct debug_event *event ) +{ + struct memory_view *view; + const pe_image_info_t *info; + client_ptr_t base; + + switch (event->data.code) + { + case DbgLoadDllStateChange: + base = event->data.load_dll.base; + break; + case DbgUnloadDllStateChange: + base = event->data.unload_dll.base; + break; + default: + base = 0; + break; + } + if (!base || !(view = find_mapped_view( event->sender->process, base )) || + !(info = get_view_image_info( view, &base ))) + return IMAGE_FILE_MACHINE_UNKNOWN; + return info->machine; +} + /* create a debug object */ DECL_HANDLER(create_debug_obj) { @@ -567,6 +591,7 @@ DECL_HANDLER(wait_debug_event) event->sender->process->debug_event = event; reply->pid = get_process_id( event->sender->process ); reply->tid = get_thread_id( event->sender ); + reply->machine = get_machine_from_event( event ); alloc_event_handles( event, current->process ); set_reply_data( &event->data, min( get_reply_max_size(), sizeof(event->data) )); } diff --git a/server/mapping.c b/server/mapping.c index f14ee11cc62..8c436623600 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -378,10 +378,7 @@ static void set_process_machine( struct process *process, struct memory_view *vi
static int generate_dll_event( struct thread *thread, int code, struct memory_view *view ) { - unsigned short process_machine = thread->process->machine; - if (!(view->flags & SEC_IMAGE)) return 0; - if (process_machine != native_machine && process_machine != view->image.machine) return 0; generate_debug_event( thread, code, view ); return 1; } diff --git a/server/protocol.def b/server/protocol.def index c857f72ce68..98b6a06b0cd 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1681,6 +1681,8 @@ struct process_info @REPLY process_id_t pid; /* process id */ thread_id_t tid; /* thread id */ + unsigned int machine; + int __pad; VARARG(event,debug_event); /* debug event data */ @END
diff --git a/server/request.h b/server/request.h index b8d4f6a6d5e..8f5218fc3b4 100644 --- a/server/request.h +++ b/server/request.h @@ -1153,7 +1153,9 @@ C_ASSERT( FIELD_OFFSET(struct wait_debug_event_request, debug) == 12 ); C_ASSERT( sizeof(struct wait_debug_event_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct wait_debug_event_reply, pid) == 8 ); C_ASSERT( FIELD_OFFSET(struct wait_debug_event_reply, tid) == 12 ); -C_ASSERT( sizeof(struct wait_debug_event_reply) == 16 ); +C_ASSERT( FIELD_OFFSET(struct wait_debug_event_reply, machine) == 16 ); +C_ASSERT( FIELD_OFFSET(struct wait_debug_event_reply, __pad) == 20 ); +C_ASSERT( sizeof(struct wait_debug_event_reply) == 24 ); C_ASSERT( FIELD_OFFSET(struct queue_exception_event_request, first) == 12 ); C_ASSERT( FIELD_OFFSET(struct queue_exception_event_request, code) == 16 ); C_ASSERT( FIELD_OFFSET(struct queue_exception_event_request, flags) == 20 ); diff --git a/server/trace.c b/server/trace.c index fb006f605b5..3013663d0e7 100644 --- a/server/trace.c +++ b/server/trace.c @@ -2246,6 +2246,7 @@ static void dump_wait_debug_event_reply( const struct wait_debug_event_reply *re { fprintf( stderr, " pid=%04x", req->pid ); fprintf( stderr, ", tid=%04x", req->tid ); + fprintf( stderr, ", machine=%08x", req->machine ); dump_varargs_debug_event( ", event=", cur_size ); }