Module: wine Branch: master Commit: 1bd447348402ce1b648ac48b9812a698f15df0c1 URL: https://source.winehq.org/git/wine.git/?a=commit;h=1bd447348402ce1b648ac48b9...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Jun 9 15:19:43 2021 +0200
ntdll: Create a thread to run the ctrl-C routine instead of raising an exception.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/kernelbase/console.c | 16 ---------------- dlls/ntdll/loader.c | 15 +++++++++++++++ dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/unix/loader.c | 2 ++ dlls/ntdll/unix/signal_arm.c | 7 +++++-- dlls/ntdll/unix/signal_arm64.c | 7 +++++-- dlls/ntdll/unix/signal_i386.c | 9 +++++++-- dlls/ntdll/unix/signal_x86_64.c | 7 +++++-- dlls/ntdll/unix/unix_private.h | 1 + programs/conhost/conhost.c | 10 ---------- 10 files changed, 41 insertions(+), 34 deletions(-)
diff --git a/dlls/kernelbase/console.c b/dlls/kernelbase/console.c index 6a3bfdeba65..c38e8e91955 100644 --- a/dlls/kernelbase/console.c +++ b/dlls/kernelbase/console.c @@ -470,20 +470,6 @@ DWORD WINAPI CtrlRoutine( void *arg ) }
-static LONG WINAPI handle_ctrl_c( EXCEPTION_POINTERS *eptr ) -{ - if (eptr->ExceptionRecord->ExceptionCode != CONTROL_C_EXIT) return EXCEPTION_CONTINUE_SEARCH; - if (!RtlGetCurrentPeb()->ProcessParameters->ConsoleHandle) return EXCEPTION_CONTINUE_SEARCH; - - if (!(NtCurrentTeb()->Peb->ProcessParameters->ConsoleFlags & 1)) - { - HANDLE thread = CreateThread( NULL, 0, CtrlRoutine, (void*)CTRL_C_EVENT, 0, NULL ); - if (thread) CloseHandle( thread ); - } - return EXCEPTION_CONTINUE_EXECUTION; -} - - /****************************************************************************** * FillConsoleOutputAttribute (kernelbase.@) */ @@ -1854,6 +1840,4 @@ void init_console( void ) AllocConsole(); } else if (params->ConsoleHandle) create_console_connection( params->ConsoleHandle ); - - RtlAddVectoredExceptionHandler( FALSE, handle_ctrl_c ); } diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index e19b62cdaaf..54806b0ab22 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -72,6 +72,8 @@ typedef void (CALLBACK *LDRENUMPROC)(LDR_DATA_TABLE_ENTRY *, void *, BOOLEAN *)
void (FASTCALL *pBaseThreadInitThunk)(DWORD,LPTHREAD_START_ROUTINE,void *) = NULL;
+static DWORD (WINAPI *pCtrlRoutine)(void *); + const struct unix_funcs *unix_funcs = NULL;
/* windows directory */ @@ -2939,6 +2941,17 @@ NTSTATUS __cdecl __wine_init_unix_lib( HMODULE module, DWORD reason, const void }
+/*********************************************************************** + * __wine_ctrl_routine + */ +NTSTATUS WINAPI __wine_ctrl_routine( void *arg ) +{ + DWORD ret = 0; + + if (pCtrlRoutine && NtCurrentTeb()->Peb->ProcessParameters->ConsoleHandle) ret = pCtrlRoutine( arg ); + RtlExitUserThread( ret ); +} + /****************************************************************** * LdrLoadDll (NTDLL.@) */ @@ -3773,6 +3786,8 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR MESSAGE( "wine: could not find BaseThreadInitThunk in kernel32.dll, status %x\n", status ); NtTerminateProcess( GetCurrentProcess(), status ); } + RtlInitAnsiString( &func_name, "CtrlRoutine" ); + LdrGetProcedureAddress( kernel32_handle, &func_name, 0, (void **)&pCtrlRoutine );
actctx_init(); if (wm->ldr.Flags & LDR_COR_ILONLY) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 9113a5d54dc..6bd6579d432 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -1616,6 +1616,7 @@ @ cdecl -syscall __wine_unix_call(int64 long ptr) @ cdecl __wine_set_unix_funcs(long ptr) @ cdecl __wine_init_unix_lib(long long ptr ptr) +@ stdcall __wine_ctrl_routine(ptr) @ extern __wine_syscall_dispatcher @ extern -arch=i386 __wine_ldt_copy
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 1830c4fb392..268f85994ae 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -109,6 +109,7 @@ void (WINAPI *pKiUserApcDispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,P NTSTATUS (WINAPI *pKiUserExceptionDispatcher)(EXCEPTION_RECORD*,CONTEXT*) = NULL; void (WINAPI *pLdrInitializeThunk)(CONTEXT*,void**,ULONG_PTR,ULONG_PTR) = NULL; void (WINAPI *pRtlUserThreadStart)( PRTL_THREAD_START_ROUTINE entry, void *arg ) = NULL; +void (WINAPI *p__wine_ctrl_routine)(void*);
static NTSTATUS (CDECL *p__wine_set_unix_funcs)( int version, const struct unix_funcs *funcs );
@@ -836,6 +837,7 @@ static void load_ntdll_functions( HMODULE module ) GET_FUNC( KiUserApcDispatcher ); GET_FUNC( LdrInitializeThunk ); GET_FUNC( RtlUserThreadStart ); + GET_FUNC( __wine_ctrl_routine ); GET_FUNC( __wine_set_unix_funcs ); #undef GET_FUNC #define SET_PTR(name,val) \ diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c index 3397e876722..0dba9cada94 100644 --- a/dlls/ntdll/unix/signal_arm.c +++ b/dlls/ntdll/unix/signal_arm.c @@ -716,9 +716,12 @@ static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext ) */ static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { - EXCEPTION_RECORD rec = { CONTROL_C_EXIT }; + HANDLE handle;
- setup_exception( sigcontext, &rec ); + if (!p__wine_ctrl_routine) return; + if (!NtCreateThreadEx( &handle, THREAD_ALL_ACCESS, NULL, NtCurrentProcess(), + p__wine_ctrl_routine, 0 /* CTRL_C_EVENT */, 0, 0, 0, 0, NULL )) + NtClose( handle ); }
diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c index 5552704987f..a65184ba0a4 100644 --- a/dlls/ntdll/unix/signal_arm64.c +++ b/dlls/ntdll/unix/signal_arm64.c @@ -878,9 +878,12 @@ static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext ) */ static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { - EXCEPTION_RECORD rec = { CONTROL_C_EXIT }; + HANDLE handle;
- setup_exception( sigcontext, &rec ); + if (!p__wine_ctrl_routine) return; + if (!NtCreateThreadEx( &handle, THREAD_ALL_ACCESS, NULL, NtCurrentProcess(), + p__wine_ctrl_routine, 0 /* CTRL_C_EVENT */, 0, 0, 0, 0, NULL )) + NtClose( handle ); }
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 7aba553216f..b5afbcf0aac 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -1956,9 +1956,14 @@ static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext ) */ static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { - EXCEPTION_RECORD rec = { CONTROL_C_EXIT }; + HANDLE handle;
- setup_exception( sigcontext, &rec ); + init_handler( sigcontext ); + + if (!p__wine_ctrl_routine) return; + if (!NtCreateThreadEx( &handle, THREAD_ALL_ACCESS, NULL, NtCurrentProcess(), + p__wine_ctrl_routine, 0 /* CTRL_C_EVENT */, 0, 0, 0, 0, NULL )) + NtClose( handle ); }
/********************************************************************** diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 524c9348ec2..148e3641d0e 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -2427,9 +2427,12 @@ static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext ) */ static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { - EXCEPTION_RECORD rec = { CONTROL_C_EXIT }; + HANDLE handle;
- setup_exception( sigcontext, &rec ); + if (!p__wine_ctrl_routine) return; + if (!NtCreateThreadEx( &handle, THREAD_ALL_ACCESS, NULL, NtCurrentProcess(), + p__wine_ctrl_routine, 0 /* CTRL_C_EVENT */, 0, 0, 0, 0, NULL )) + NtClose( handle ); }
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index 39ab7912490..5ebbc6d702b 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -100,6 +100,7 @@ extern void (WINAPI *pKiUserApcDispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULON extern NTSTATUS (WINAPI *pKiUserExceptionDispatcher)(EXCEPTION_RECORD*,CONTEXT*) DECLSPEC_HIDDEN; extern void (WINAPI *pLdrInitializeThunk)(CONTEXT*,void**,ULONG_PTR,ULONG_PTR) DECLSPEC_HIDDEN; extern void (WINAPI *pRtlUserThreadStart)( PRTL_THREAD_START_ROUTINE entry, void *arg ) DECLSPEC_HIDDEN; +extern void (WINAPI *p__wine_ctrl_routine)(void *) DECLSPEC_HIDDEN; extern NTSTATUS CDECL fast_RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit, int timeout ) DECLSPEC_HIDDEN; extern NTSTATUS CDECL fast_RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit ) DECLSPEC_HIDDEN; extern NTSTATUS CDECL fast_RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit ) DECLSPEC_HIDDEN; diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c index dd423ee5491..86dadad9277 100644 --- a/programs/conhost/conhost.c +++ b/programs/conhost/conhost.c @@ -2713,14 +2713,6 @@ static int main_loop( struct console *console, HANDLE signal ) return 0; }
-static LONG WINAPI handle_ctrl_c( EXCEPTION_POINTERS *eptr ) -{ - if (eptr->ExceptionRecord->ExceptionCode != CONTROL_C_EXIT) return EXCEPTION_CONTINUE_SEARCH; - /* In Unix mode, ignore ctrl c exceptions. Signals are sent it to clients as well and we will - * terminate the usual way if they don't handle it. */ - return EXCEPTION_CONTINUE_EXECUTION; -} - int __cdecl wmain(int argc, WCHAR *argv[]) { int headless = 0, i, width = 0, height = 0; @@ -2810,7 +2802,5 @@ int __cdecl wmain(int argc, WCHAR *argv[]) ShowWindow( console.win, (si.dwFlags & STARTF_USESHOWWINDOW) ? si.wShowWindow : SW_SHOW ); }
- if (console.is_unix) RtlAddVectoredExceptionHandler( FALSE, handle_ctrl_c ); - return main_loop( &console, signal ); }