wow64: Move filter of (un)load DLL debug events to client side.
Code is duplicated in ntdll.dll (for 32bit only and old Wow configuration) and wow64.dll for new Wow64 configurations. Signed-off-by: Eric Pouech <eric.pouech@gmail.com>
This commit is contained in:
parent
d203beb5e5
commit
4b28127157
3 changed files with 118 additions and 5 deletions
|
@ -1008,15 +1008,48 @@ static NTSTATUS event_data_to_state_change( const debug_event_t *data, DBGUI_WAI
|
|||
info->DebugInfoFileOffset = data->load_dll.dbg_offset;
|
||||
info->DebugInfoSize = data->load_dll.dbg_size;
|
||||
info->NamePointer = wine_server_get_ptr( data->load_dll.name );
|
||||
if ((DWORD_PTR)data->load_dll.base != data->load_dll.base)
|
||||
return STATUS_PARTIAL_COPY;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
case DbgUnloadDllStateChange:
|
||||
state->StateInfo.UnloadDll.BaseAddress = wine_server_get_ptr( data->unload_dll.base );
|
||||
if ((DWORD_PTR)data->unload_dll.base != data->unload_dll.base)
|
||||
return STATUS_PARTIAL_COPY;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
#ifndef _WIN64
|
||||
/* helper to NtWaitForDebugEvent; retrive machine from PE image */
|
||||
static NTSTATUS get_image_machine( HANDLE handle, USHORT *machine )
|
||||
{
|
||||
IMAGE_DOS_HEADER dos_hdr;
|
||||
IMAGE_NT_HEADERS nt_hdr;
|
||||
IO_STATUS_BLOCK iosb;
|
||||
LARGE_INTEGER offset;
|
||||
FILE_POSITION_INFORMATION pos_info;
|
||||
NTSTATUS status;
|
||||
|
||||
offset.QuadPart = 0;
|
||||
status = NtReadFile( handle, NULL, NULL, NULL,
|
||||
&iosb, &dos_hdr, sizeof(dos_hdr), &offset, NULL );
|
||||
if (!status)
|
||||
{
|
||||
offset.QuadPart = dos_hdr.e_lfanew;
|
||||
status = NtReadFile( handle, NULL, NULL, NULL, &iosb,
|
||||
&nt_hdr, FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader), &offset, NULL );
|
||||
if (!status)
|
||||
*machine = nt_hdr.FileHeader.Machine;
|
||||
/* Reset file pos at beginning of file */
|
||||
pos_info.CurrentByteOffset.QuadPart = 0;
|
||||
NtSetInformationFile( handle, &iosb, &pos_info, sizeof(pos_info), FilePositionInformation );
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
* NtWaitForDebugEvent (NTDLL.@)
|
||||
*/
|
||||
|
@ -1034,8 +1067,9 @@ NTSTATUS WINAPI NtWaitForDebugEvent( HANDLE handle, BOOLEAN alertable, LARGE_INT
|
|||
req->debug = wine_server_obj_handle( handle );
|
||||
wine_server_set_reply( req, &data, sizeof(data) );
|
||||
ret = wine_server_call( req );
|
||||
if (!ret && !(ret = event_data_to_state_change( &data, state )))
|
||||
if (!ret)
|
||||
{
|
||||
ret = event_data_to_state_change( &data, state );
|
||||
state->NewState = data.code;
|
||||
state->AppClientId.UniqueProcess = ULongToHandle( reply->pid );
|
||||
state->AppClientId.UniqueThread = ULongToHandle( reply->tid );
|
||||
|
@ -1043,6 +1077,24 @@ NTSTATUS WINAPI NtWaitForDebugEvent( HANDLE handle, BOOLEAN alertable, LARGE_INT
|
|||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
#ifndef _WIN64
|
||||
/* don't pass 64bit load events to 32bit callers */
|
||||
if (!ret && state->NewState == DbgLoadDllStateChange)
|
||||
{
|
||||
USHORT machine;
|
||||
if (!get_image_machine( state->StateInfo.LoadDll.FileHandle, &machine ) &&
|
||||
machine != current_machine)
|
||||
ret = STATUS_PARTIAL_COPY;
|
||||
}
|
||||
if (ret == STATUS_PARTIAL_COPY)
|
||||
{
|
||||
if (state->NewState == DbgLoadDllStateChange)
|
||||
NtClose( state->StateInfo.LoadDll.FileHandle );
|
||||
NtDebugContinue( handle, &state->AppClientId, DBG_CONTINUE );
|
||||
wait = TRUE;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (ret != STATUS_PENDING) return ret;
|
||||
if (!wait) return STATUS_TIMEOUT;
|
||||
wait = FALSE;
|
||||
|
|
|
@ -1490,6 +1490,65 @@ NTSTATUS WINAPI wow64_NtWaitForAlertByThreadId( UINT *args )
|
|||
}
|
||||
|
||||
|
||||
/* helper to wow64_NtWaitForDebugEvent; retrive machine from PE image */
|
||||
static NTSTATUS get_image_machine( HANDLE handle, USHORT *machine )
|
||||
{
|
||||
IMAGE_DOS_HEADER dos_hdr;
|
||||
IMAGE_NT_HEADERS nt_hdr;
|
||||
IO_STATUS_BLOCK iosb;
|
||||
LARGE_INTEGER offset;
|
||||
FILE_POSITION_INFORMATION pos_info;
|
||||
NTSTATUS status;
|
||||
|
||||
offset.QuadPart = 0;
|
||||
status = NtReadFile( handle, NULL, NULL, NULL,
|
||||
&iosb, &dos_hdr, sizeof(dos_hdr), &offset, NULL );
|
||||
if (!status)
|
||||
{
|
||||
offset.QuadPart = dos_hdr.e_lfanew;
|
||||
status = NtReadFile( handle, NULL, NULL, NULL, &iosb,
|
||||
&nt_hdr, FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader), &offset, NULL );
|
||||
if (!status)
|
||||
*machine = nt_hdr.FileHeader.Machine;
|
||||
/* Reset file pos at beginning of file */
|
||||
pos_info.CurrentByteOffset.QuadPart = 0;
|
||||
NtSetInformationFile( handle, &iosb, &pos_info, sizeof(pos_info), FilePositionInformation );
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/* helper to wow64_NtWaitForDebugEvent; only pass debug events for current machine */
|
||||
static BOOL filter_out_state_change( HANDLE handle, DBGUI_WAIT_STATE_CHANGE *state )
|
||||
{
|
||||
BOOL filter_out;
|
||||
|
||||
switch (state->NewState)
|
||||
{
|
||||
case DbgLoadDllStateChange:
|
||||
filter_out = ((ULONG64)state->StateInfo.LoadDll.BaseOfDll >> 32) != 0;
|
||||
if (!filter_out)
|
||||
{
|
||||
USHORT machine;
|
||||
filter_out = !get_image_machine( state->StateInfo.LoadDll.FileHandle, &machine) && machine != current_machine;
|
||||
}
|
||||
break;
|
||||
case DbgUnloadDllStateChange:
|
||||
filter_out = ((ULONG_PTR)state->StateInfo.UnloadDll.BaseAddress >> 32) != 0;
|
||||
break;
|
||||
default:
|
||||
filter_out = FALSE;
|
||||
break;
|
||||
}
|
||||
if (filter_out)
|
||||
{
|
||||
if (state->NewState == DbgLoadDllStateChange)
|
||||
NtClose( state->StateInfo.LoadDll.FileHandle );
|
||||
NtDebugContinue( handle, &state->AppClientId, DBG_CONTINUE );
|
||||
}
|
||||
return filter_out;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* wow64_NtWaitForDebugEvent
|
||||
*/
|
||||
|
@ -1502,7 +1561,12 @@ NTSTATUS WINAPI wow64_NtWaitForDebugEvent( UINT *args )
|
|||
|
||||
ULONG i;
|
||||
DBGUI_WAIT_STATE_CHANGE state;
|
||||
NTSTATUS status = NtWaitForDebugEvent( handle, alertable, timeout, &state );
|
||||
NTSTATUS status;
|
||||
|
||||
do
|
||||
{
|
||||
status = NtWaitForDebugEvent( handle, alertable, timeout, &state );
|
||||
} while (!status && filter_out_state_change( handle, &state ));
|
||||
|
||||
if (!status)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue