Commit 1bd44734 authored by Alexandre Julliard's avatar Alexandre Julliard

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

parent 21fa0419
...@@ -470,20 +470,6 @@ DWORD WINAPI CtrlRoutine( void *arg ) ...@@ -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.@) * FillConsoleOutputAttribute (kernelbase.@)
*/ */
...@@ -1854,6 +1840,4 @@ void init_console( void ) ...@@ -1854,6 +1840,4 @@ void init_console( void )
AllocConsole(); AllocConsole();
} }
else if (params->ConsoleHandle) create_console_connection( params->ConsoleHandle ); else if (params->ConsoleHandle) create_console_connection( params->ConsoleHandle );
RtlAddVectoredExceptionHandler( FALSE, handle_ctrl_c );
} }
...@@ -72,6 +72,8 @@ typedef void (CALLBACK *LDRENUMPROC)(LDR_DATA_TABLE_ENTRY *, void *, BOOLEAN *) ...@@ -72,6 +72,8 @@ typedef void (CALLBACK *LDRENUMPROC)(LDR_DATA_TABLE_ENTRY *, void *, BOOLEAN *)
void (FASTCALL *pBaseThreadInitThunk)(DWORD,LPTHREAD_START_ROUTINE,void *) = NULL; void (FASTCALL *pBaseThreadInitThunk)(DWORD,LPTHREAD_START_ROUTINE,void *) = NULL;
static DWORD (WINAPI *pCtrlRoutine)(void *);
const struct unix_funcs *unix_funcs = NULL; const struct unix_funcs *unix_funcs = NULL;
/* windows directory */ /* windows directory */
...@@ -2939,6 +2941,17 @@ NTSTATUS __cdecl __wine_init_unix_lib( HMODULE module, DWORD reason, const void ...@@ -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.@) * LdrLoadDll (NTDLL.@)
*/ */
...@@ -3773,6 +3786,8 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR ...@@ -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 ); MESSAGE( "wine: could not find BaseThreadInitThunk in kernel32.dll, status %x\n", status );
NtTerminateProcess( GetCurrentProcess(), status ); NtTerminateProcess( GetCurrentProcess(), status );
} }
RtlInitAnsiString( &func_name, "CtrlRoutine" );
LdrGetProcedureAddress( kernel32_handle, &func_name, 0, (void **)&pCtrlRoutine );
actctx_init(); actctx_init();
if (wm->ldr.Flags & LDR_COR_ILONLY) if (wm->ldr.Flags & LDR_COR_ILONLY)
......
...@@ -1616,6 +1616,7 @@ ...@@ -1616,6 +1616,7 @@
@ cdecl -syscall __wine_unix_call(int64 long ptr) @ cdecl -syscall __wine_unix_call(int64 long ptr)
@ cdecl __wine_set_unix_funcs(long ptr) @ cdecl __wine_set_unix_funcs(long ptr)
@ cdecl __wine_init_unix_lib(long long ptr ptr) @ cdecl __wine_init_unix_lib(long long ptr ptr)
@ stdcall __wine_ctrl_routine(ptr)
@ extern __wine_syscall_dispatcher @ extern __wine_syscall_dispatcher
@ extern -arch=i386 __wine_ldt_copy @ extern -arch=i386 __wine_ldt_copy
......
...@@ -109,6 +109,7 @@ void (WINAPI *pKiUserApcDispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,P ...@@ -109,6 +109,7 @@ void (WINAPI *pKiUserApcDispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,P
NTSTATUS (WINAPI *pKiUserExceptionDispatcher)(EXCEPTION_RECORD*,CONTEXT*) = NULL; NTSTATUS (WINAPI *pKiUserExceptionDispatcher)(EXCEPTION_RECORD*,CONTEXT*) = NULL;
void (WINAPI *pLdrInitializeThunk)(CONTEXT*,void**,ULONG_PTR,ULONG_PTR) = NULL; void (WINAPI *pLdrInitializeThunk)(CONTEXT*,void**,ULONG_PTR,ULONG_PTR) = NULL;
void (WINAPI *pRtlUserThreadStart)( PRTL_THREAD_START_ROUTINE entry, void *arg ) = 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 ); 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 ) ...@@ -836,6 +837,7 @@ static void load_ntdll_functions( HMODULE module )
GET_FUNC( KiUserApcDispatcher ); GET_FUNC( KiUserApcDispatcher );
GET_FUNC( LdrInitializeThunk ); GET_FUNC( LdrInitializeThunk );
GET_FUNC( RtlUserThreadStart ); GET_FUNC( RtlUserThreadStart );
GET_FUNC( __wine_ctrl_routine );
GET_FUNC( __wine_set_unix_funcs ); GET_FUNC( __wine_set_unix_funcs );
#undef GET_FUNC #undef GET_FUNC
#define SET_PTR(name,val) \ #define SET_PTR(name,val) \
......
...@@ -716,9 +716,12 @@ static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext ) ...@@ -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 ) 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 );
} }
......
...@@ -878,9 +878,12 @@ static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext ) ...@@ -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 ) 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 );
} }
......
...@@ -1956,9 +1956,14 @@ static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext ) ...@@ -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 ) 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 );
} }
/********************************************************************** /**********************************************************************
......
...@@ -2427,9 +2427,12 @@ static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext ) ...@@ -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 ) 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 );
} }
......
...@@ -100,6 +100,7 @@ extern void (WINAPI *pKiUserApcDispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULON ...@@ -100,6 +100,7 @@ extern void (WINAPI *pKiUserApcDispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULON
extern NTSTATUS (WINAPI *pKiUserExceptionDispatcher)(EXCEPTION_RECORD*,CONTEXT*) DECLSPEC_HIDDEN; extern NTSTATUS (WINAPI *pKiUserExceptionDispatcher)(EXCEPTION_RECORD*,CONTEXT*) DECLSPEC_HIDDEN;
extern void (WINAPI *pLdrInitializeThunk)(CONTEXT*,void**,ULONG_PTR,ULONG_PTR) 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 *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_RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit, int timeout ) DECLSPEC_HIDDEN;
extern NTSTATUS CDECL fast_RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit ) DECLSPEC_HIDDEN; extern NTSTATUS CDECL fast_RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit ) DECLSPEC_HIDDEN;
extern NTSTATUS CDECL fast_RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit ) DECLSPEC_HIDDEN; extern NTSTATUS CDECL fast_RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit ) DECLSPEC_HIDDEN;
......
...@@ -2713,14 +2713,6 @@ static int main_loop( struct console *console, HANDLE signal ) ...@@ -2713,14 +2713,6 @@ static int main_loop( struct console *console, HANDLE signal )
return 0; 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 __cdecl wmain(int argc, WCHAR *argv[])
{ {
int headless = 0, i, width = 0, height = 0; int headless = 0, i, width = 0, height = 0;
...@@ -2810,7 +2802,5 @@ int __cdecl wmain(int argc, WCHAR *argv[]) ...@@ -2810,7 +2802,5 @@ int __cdecl wmain(int argc, WCHAR *argv[])
ShowWindow( console.win, (si.dwFlags & STARTF_USESHOWWINDOW) ? si.wShowWindow : SW_SHOW ); 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 ); return main_loop( &console, signal );
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment