Alexandre Julliard : ntdll: Create a thread to run the ctrl-C routine instead of raising an exception.

Alexandre Julliard julliard at winehq.org
Wed Jun 9 16:43:06 CDT 2021


Module: wine
Branch: master
Commit: 1bd447348402ce1b648ac48b9812a698f15df0c1
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=1bd447348402ce1b648ac48b9812a698f15df0c1

Author: Alexandre Julliard <julliard at 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 at 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 );
 }




More information about the wine-cvs mailing list