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

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-06-09 15:19:43 +02:00
parent 21fa04194c
commit 1bd4473484
10 changed files with 41 additions and 34 deletions

View File

@ -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 );
}

View File

@ -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)

View File

@ -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

View File

@ -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) \

View File

@ -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 );
}

View File

@ -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 );
}

View File

@ -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 );
}
/**********************************************************************

View File

@ -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 );
}

View File

@ -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;

View File

@ -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 );
}