From 90e38659291dc475f3340427580a170408289861 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 10 Jan 2006 17:51:22 +0100 Subject: [PATCH] ntdll: NtRaiseException doesn't need to be a register function. Moved common code between NtRaiseException and RtlRaiseException to a separate raise_exception function. --- dlls/ntdll/exception.c | 199 ++++++++++++++++++++++------------------- dlls/ntdll/ntdll.spec | 2 +- include/winternl.h | 2 +- 3 files changed, 110 insertions(+), 93 deletions(-) diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c index ee1bf9c6a00..d4c4b32c6a0 100644 --- a/dlls/ntdll/exception.c +++ b/dlls/ntdll/exception.c @@ -77,6 +77,7 @@ static RTL_CRITICAL_SECTION vectored_handlers_section = { &critsect_debug, -1, 0 # error You must define GET_IP for this CPU #endif +extern void DECLSPEC_NORETURN __wine_call_from_32_restore_regs( const CONTEXT *context ); /******************************************************************* * EXC_RaiseHandler @@ -241,65 +242,15 @@ static LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context ) } -/******************************************************************* - * EXC_DefaultHandling +/********************************************************************** + * call_stack_handlers * - * Default handling for exceptions. Called when we didn't find a suitable handler. + * Call the stack handlers chain. */ -static void EXC_DefaultHandling( EXCEPTION_RECORD *rec, CONTEXT *context ) -{ - if (send_debug_event( rec, FALSE, context ) == DBG_CONTINUE) return; /* continue execution */ - - if (rec->ExceptionFlags & EH_STACK_INVALID) - ERR("Exception frame is not in stack limits => unable to dispatch exception.\n"); - else if (rec->ExceptionCode == STATUS_NONCONTINUABLE_EXCEPTION) - ERR("Process attempted to continue execution after noncontinuable exception.\n"); - else - ERR("Unhandled exception code %lx flags %lx addr %p\n", - rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress ); - NtTerminateProcess( NtCurrentProcess(), 1 ); -} - - -/*********************************************************************** - * RtlRaiseException (NTDLL.@) - */ -void WINAPI __regs_RtlRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context ) +static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *context ) { EXCEPTION_REGISTRATION_RECORD *frame, *dispatch, *nested_frame; - EXCEPTION_RECORD newrec; - DWORD res, c; - NTSTATUS status; - - TRACE( "code=%lx flags=%lx addr=%p\n", rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress ); - for (c=0; cNumberParameters; c++) TRACE(" info[%ld]=%08lx\n", c, rec->ExceptionInformation[c]); - if (rec->ExceptionCode == EXCEPTION_WINE_STUB) - { - if (HIWORD(rec->ExceptionInformation[1])) - MESSAGE( "wine: Call from %p to unimplemented function %s.%s, aborting\n", - rec->ExceptionAddress, - (char*)rec->ExceptionInformation[0], (char*)rec->ExceptionInformation[1] ); - else - MESSAGE( "wine: Call from %p to unimplemented function %s.%ld, aborting\n", - rec->ExceptionAddress, - (char*)rec->ExceptionInformation[0], rec->ExceptionInformation[1] ); - } -#ifdef __i386__ - else - { - TRACE(" eax=%08lx ebx=%08lx ecx=%08lx edx=%08lx esi=%08lx edi=%08lx\n", - context->Eax, context->Ebx, context->Ecx, - context->Edx, context->Esi, context->Edi ); - TRACE(" ebp=%08lx esp=%08lx cs=%04lx ds=%04lx es=%04lx fs=%04lx gs=%04lx flags=%08lx\n", - context->Ebp, context->Esp, context->SegCs, context->SegDs, - context->SegEs, context->SegFs, context->SegGs, context->EFlags ); - } -#endif - - status = send_debug_event( rec, TRUE, context ); - if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED) return; /* continue execution */ - - if (call_vectored_handlers( rec, context ) == EXCEPTION_CONTINUE_EXECUTION) return; + DWORD res; frame = NtCurrentTeb()->Tib.ExceptionList; nested_frame = NULL; @@ -326,13 +277,8 @@ void WINAPI __regs_RtlRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context ) switch(res) { case ExceptionContinueExecution: - if (!(rec->ExceptionFlags & EH_NONCONTINUABLE)) return; - newrec.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION; - newrec.ExceptionFlags = EH_NONCONTINUABLE; - newrec.ExceptionRecord = rec; - newrec.NumberParameters = 0; - RtlRaiseException( &newrec ); /* never returns */ - break; + if (!(rec->ExceptionFlags & EH_NONCONTINUABLE)) return STATUS_SUCCESS; + return STATUS_NONCONTINUABLE_EXCEPTION; case ExceptionContinueSearch: break; case ExceptionNestedException: @@ -340,16 +286,109 @@ void WINAPI __regs_RtlRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context ) rec->ExceptionFlags |= EH_NESTED_CALL; break; default: - newrec.ExceptionCode = STATUS_INVALID_DISPOSITION; - newrec.ExceptionFlags = EH_NONCONTINUABLE; - newrec.ExceptionRecord = rec; - newrec.NumberParameters = 0; - RtlRaiseException( &newrec ); /* never returns */ - break; + return STATUS_INVALID_DISPOSITION; } frame = frame->Prev; } - EXC_DefaultHandling( rec, context ); + return STATUS_UNHANDLED_EXCEPTION; +} + + +/******************************************************************* + * raise_exception + * + * Implementation of NtRaiseException. + */ +static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance ) +{ + NTSTATUS status; + + if (first_chance) + { + DWORD c; + + TRACE( "code=%lx flags=%lx addr=%p\n", + rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress ); + for (c = 0; c < rec->NumberParameters; c++) + TRACE( " info[%ld]=%08lx\n", c, rec->ExceptionInformation[c] ); + if (rec->ExceptionCode == EXCEPTION_WINE_STUB) + { + if (rec->ExceptionInformation[1] >> 16) + MESSAGE( "wine: Call from %p to unimplemented function %s.%s, aborting\n", + rec->ExceptionAddress, + (char*)rec->ExceptionInformation[0], (char*)rec->ExceptionInformation[1] ); + else + MESSAGE( "wine: Call from %p to unimplemented function %s.%ld, aborting\n", + rec->ExceptionAddress, + (char*)rec->ExceptionInformation[0], rec->ExceptionInformation[1] ); + } +#ifdef __i386__ + else + { + TRACE(" eax=%08lx ebx=%08lx ecx=%08lx edx=%08lx esi=%08lx edi=%08lx\n", + context->Eax, context->Ebx, context->Ecx, + context->Edx, context->Esi, context->Edi ); + TRACE(" ebp=%08lx esp=%08lx cs=%04lx ds=%04lx es=%04lx fs=%04lx gs=%04lx flags=%08lx\n", + context->Ebp, context->Esp, context->SegCs, context->SegDs, + context->SegEs, context->SegFs, context->SegGs, context->EFlags ); + } +#endif + status = send_debug_event( rec, TRUE, context ); + if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED) + return STATUS_SUCCESS; + + if (call_vectored_handlers( rec, context ) == EXCEPTION_CONTINUE_EXECUTION) + return STATUS_SUCCESS; + + if ((status = call_stack_handlers( rec, context )) != STATUS_UNHANDLED_EXCEPTION) + return status; + } + + /* last chance exception */ + + status = send_debug_event( rec, FALSE, context ); + if (status != DBG_CONTINUE) + { + if (rec->ExceptionFlags & EH_STACK_INVALID) + ERR("Exception frame is not in stack limits => unable to dispatch exception.\n"); + else if (rec->ExceptionCode == STATUS_NONCONTINUABLE_EXCEPTION) + ERR("Process attempted to continue execution after noncontinuable exception.\n"); + else + ERR("Unhandled exception code %lx flags %lx addr %p\n", + rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress ); + NtTerminateProcess( NtCurrentProcess(), 1 ); + } + return STATUS_SUCCESS; +} + + +/******************************************************************* + * NtRaiseException (NTDLL.@) + */ +NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance ) +{ + NTSTATUS status = raise_exception( rec, context, first_chance ); +#ifdef DEFINE_REGS_ENTRYPOINT + if (status == STATUS_SUCCESS) __wine_call_from_32_restore_regs( context ); +#endif + return status; +} + +/*********************************************************************** + * RtlRaiseException (NTDLL.@) + */ +void WINAPI __regs_RtlRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context ) +{ + NTSTATUS status = raise_exception( rec, context, TRUE ); + if (status != STATUS_SUCCESS) + { + EXCEPTION_RECORD newrec; + newrec.ExceptionCode = status; + newrec.ExceptionFlags = EH_NONCONTINUABLE; + newrec.ExceptionRecord = rec; + newrec.NumberParameters = 0; + RtlRaiseException( &newrec ); /* never returns */ + } } /**********************************************************************/ @@ -454,28 +493,6 @@ void WINAPI RtlUnwind( PVOID pEndFrame, PVOID unusedEip, #endif -/******************************************************************* - * NtRaiseException (NTDLL.@) - */ -void WINAPI __regs_NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *ctx, - BOOL first, CONTEXT *context ) -{ - __regs_RtlRaiseException( rec, ctx ); - *context = *ctx; -} - -#ifdef DEFINE_REGS_ENTRYPOINT -DEFINE_REGS_ENTRYPOINT( NtRaiseException, 12, 12 ); -#else -void WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *ctx, BOOL first ) -{ - CONTEXT context; - memset( &context, 0, sizeof(context) ); - __regs_NtRaiseException( rec, ctx, first, &context ); -} -#endif - - /*********************************************************************** * RtlRaiseStatus (NTDLL.@) * diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index b3efbe062a9..22fe7dadac8 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -273,7 +273,7 @@ @ stdcall NtQueryVirtualMemory(long ptr long ptr long ptr) @ stdcall NtQueryVolumeInformationFile(long ptr ptr long long) @ stdcall NtQueueApcThread(long ptr long long long) -@ stdcall -register NtRaiseException(ptr ptr long) +@ stdcall NtRaiseException(ptr ptr long) @ stub NtRaiseHardError @ stdcall NtReadFile(long long long long long long long long long) @ stub NtReadFileScatter diff --git a/include/winternl.h b/include/winternl.h index dcd251e05b4..0a7b11065b9 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -1841,7 +1841,7 @@ NTSTATUS WINAPI NtQueryTimerResolution(PULONG,PULONG,PULONG); NTSTATUS WINAPI NtQueryValueKey(HANDLE,const UNICODE_STRING *,KEY_VALUE_INFORMATION_CLASS,void *,DWORD,DWORD *); NTSTATUS WINAPI NtQueryVirtualMemory(HANDLE,LPCVOID,MEMORY_INFORMATION_CLASS,PVOID,SIZE_T,SIZE_T*); NTSTATUS WINAPI NtQueryVolumeInformationFile(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONG,FS_INFORMATION_CLASS); -void WINAPI NtRaiseException(PEXCEPTION_RECORD,PCONTEXT,BOOL); +NTSTATUS WINAPI NtRaiseException(PEXCEPTION_RECORD,PCONTEXT,BOOL); NTSTATUS WINAPI NtRaiseHardError(NTSTATUS,ULONG,PUNICODE_STRING,PVOID*,HARDERROR_RESPONSE_OPTION,PHARDERROR_RESPONSE); NTSTATUS WINAPI NtReadFile(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,PVOID,ULONG,PLARGE_INTEGER,PULONG); NTSTATUS WINAPI NtReadFileScatter(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,FILE_SEGMENT_ELEMENT,ULONG,PLARGE_INTEGER,PULONG);