From 23081203348ee9b93e6deb1bd986697807450219 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 20 Aug 2021 15:07:06 +0200 Subject: [PATCH] wow64: Forward 64-bit invalid handle exceptions to the 32-bit guest. Signed-off-by: Alexandre Julliard --- dlls/wow64/process.c | 21 +++++++++++++++++++++ dlls/wow64/syscall.c | 17 ++++++++++++++++- dlls/wow64/wow64.spec | 2 +- dlls/wow64/wow64_private.h | 5 +++-- 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/dlls/wow64/process.c b/dlls/wow64/process.c index 5e0fedd136f..d66b973385b 100644 --- a/dlls/wow64/process.c +++ b/dlls/wow64/process.c @@ -1251,3 +1251,24 @@ NTSTATUS WINAPI wow64_NtTerminateThread( UINT *args ) return NtTerminateThread( handle, exit_code ); } + + +/********************************************************************** + * Wow64PassExceptionToGuest (wow64.@) + */ +void WINAPI Wow64PassExceptionToGuest( EXCEPTION_POINTERS *ptrs ) +{ + EXCEPTION_RECORD *rec = ptrs->ExceptionRecord; + EXCEPTION_RECORD32 rec32; + ULONG i; + + rec32.ExceptionCode = rec->ExceptionCode; + rec32.ExceptionFlags = rec->ExceptionFlags; + rec32.ExceptionRecord = PtrToUlong( rec->ExceptionRecord ); + rec32.ExceptionAddress = PtrToUlong( rec->ExceptionAddress ); + rec32.NumberParameters = rec->NumberParameters; + for (i = 0; i < rec->NumberParameters; i++) + rec32.ExceptionInformation[i] = rec->ExceptionInformation[i]; + + call_user_exception_dispatcher( &rec32, NULL, ptrs->ContextRecord ); +} diff --git a/dlls/wow64/syscall.c b/dlls/wow64/syscall.c index 62399225042..91f2a029e4b 100644 --- a/dlls/wow64/syscall.c +++ b/dlls/wow64/syscall.c @@ -519,6 +519,21 @@ static void free_temp_data(void) } +/********************************************************************** + * syscall_filter + */ +static LONG CALLBACK syscall_filter( EXCEPTION_POINTERS *ptrs ) +{ + switch (ptrs->ExceptionRecord->ExceptionCode) + { + case STATUS_INVALID_HANDLE: + Wow64PassExceptionToGuest( ptrs ); + break; + } + return EXCEPTION_EXECUTE_HANDLER; +} + + /********************************************************************** * Wow64SystemServiceEx (NTDLL.@) */ @@ -536,7 +551,7 @@ NTSTATUS WINAPI Wow64SystemServiceEx( UINT num, UINT *args ) syscall_thunk thunk = syscall_thunks[syscall_map[num]]; status = thunk( args ); } - __EXCEPT_ALL + __EXCEPT( syscall_filter ) { status = GetExceptionCode(); } diff --git a/dlls/wow64/wow64.spec b/dlls/wow64/wow64.spec index 4ed20af0f29..69275b2580f 100644 --- a/dlls/wow64/wow64.spec +++ b/dlls/wow64/wow64.spec @@ -13,7 +13,7 @@ @ stdcall Wow64LdrpInitialize(ptr) @ stub Wow64LogPrint @ stub Wow64NotifyUnsimulateComplete -@ stub Wow64PassExceptionToGuest +@ stdcall Wow64PassExceptionToGuest(ptr) @ stub Wow64PrepareForDebuggerAttach @ stub Wow64PrepareForException @ stub Wow64RaiseException diff --git a/dlls/wow64/wow64_private.h b/dlls/wow64/wow64_private.h index 3b44c513fa3..370ae76a0c4 100644 --- a/dlls/wow64/wow64_private.h +++ b/dlls/wow64/wow64_private.h @@ -28,8 +28,9 @@ ALL_SYSCALLS #undef SYSCALL_ENTRY -void * WINAPI Wow64AllocateTemp( SIZE_T size ) DECLSPEC_HIDDEN; -void WINAPI Wow64ApcRoutine( ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, CONTEXT *context ) DECLSPEC_HIDDEN; +void * WINAPI Wow64AllocateTemp( SIZE_T size ); +void WINAPI Wow64ApcRoutine( ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, CONTEXT *context ); +void WINAPI Wow64PassExceptionToGuest( EXCEPTION_POINTERS *ptrs ); extern void init_file_redirects(void) DECLSPEC_HIDDEN; extern BOOL get_file_redirect( OBJECT_ATTRIBUTES *attr ) DECLSPEC_HIDDEN;