static LONG BaseThreadExceptionFilter(EXCEPTION_POINTERS * ExceptionInfo) { LONG ExceptionDisposition = EXCEPTION_EXECUTE_HANDLER; LPTOP_LEVEL_EXCEPTION_FILTER RealFilter; RealFilter = RtlDecodePointer(GlobalTopLevelExceptionFilter); if (RealFilter != NULL) { _SEH2_TRY { ExceptionDisposition = RealFilter(ExceptionInfo); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ExceptionDisposition = UnhandledExceptionFilter(ExceptionInfo); } _SEH2_END; }
BOOLEAN NTAPI RtlpCallVectoredHandlers(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context, IN PLIST_ENTRY VectoredHandlerList) { PLIST_ENTRY CurrentEntry; PRTL_VECTORED_HANDLER_ENTRY VectoredExceptionHandler; PVECTORED_EXCEPTION_HANDLER VectoredHandler; EXCEPTION_POINTERS ExceptionInfo; BOOLEAN HandlerRemoved; LONG HandlerReturn; /* * Initialize these in case there are no entries, * or if no one handled the exception */ HandlerRemoved = FALSE; HandlerReturn = EXCEPTION_CONTINUE_SEARCH; /* Set up the data to pass to the handler */ ExceptionInfo.ExceptionRecord = ExceptionRecord; ExceptionInfo.ContextRecord = Context; /* Grab the lock */ RtlEnterCriticalSection(&RtlpVectoredHandlerLock); /* Loop entries */ CurrentEntry = VectoredHandlerList->Flink; while (CurrentEntry != VectoredHandlerList) { /* Get the struct */ VectoredExceptionHandler = CONTAINING_RECORD(CurrentEntry, RTL_VECTORED_HANDLER_ENTRY, ListEntry); /* Reference it so it doesn't go away while we are using it */ VectoredExceptionHandler->Refs++; /* Drop the lock before calling the handler */ RtlLeaveCriticalSection(&RtlpVectoredHandlerLock); /* * Get the function pointer, decoding it so we will crash * if malicious code has altered it. That is, if something has * set VectoredHandler to a non-encoded pointer */ VectoredHandler = RtlDecodePointer(VectoredExceptionHandler->VectoredHandler); /* Call the handler */ HandlerReturn = VectoredHandler(&ExceptionInfo); /* Handler called -- grab the lock to dereference */ RtlEnterCriticalSection(&RtlpVectoredHandlerLock); /* Dereference and see if it got deleted */ VectoredExceptionHandler->Refs--; if (VectoredExceptionHandler->Refs == 0) { /* It did -- do we have to free it now? */ if (HandlerReturn == EXCEPTION_CONTINUE_EXECUTION) { /* We don't, just remove it from the list and break out */ RemoveEntryList(&VectoredExceptionHandler->ListEntry); HandlerRemoved = TRUE; break; } /* * Get the next entry before freeing, * and remove the current one from the list */ CurrentEntry = VectoredExceptionHandler->ListEntry.Flink; RemoveEntryList(&VectoredExceptionHandler->ListEntry); /* Free the entry outside of the lock, then reacquire it */ RtlLeaveCriticalSection(&RtlpVectoredHandlerLock); RtlFreeHeap(RtlGetProcessHeap(), 0, VectoredExceptionHandler); RtlEnterCriticalSection(&RtlpVectoredHandlerLock); } else { /* No delete -- should we continue execution? */ if (HandlerReturn == EXCEPTION_CONTINUE_EXECUTION) { /* Break out */ break; } else { /* Continue searching the list */ CurrentEntry = CurrentEntry->Flink; } } } /* Let go of the lock now */ RtlLeaveCriticalSection(&RtlpVectoredHandlerLock); /* Anything to free? */ if (HandlerRemoved) { /* Get rid of it */ RtlFreeHeap(RtlGetProcessHeap(), 0, VectoredExceptionHandler); } /* Return whether to continue execution (ignored for continue handlers) */ return (HandlerReturn == EXCEPTION_CONTINUE_EXECUTION) ? TRUE : FALSE; }
BOOLEAN NTAPI RtlCallVectoredExceptionHandlers(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context) { PLIST_ENTRY CurrentEntry; PRTL_VECTORED_EXCEPTION_HANDLER veh = NULL; PVECTORED_EXCEPTION_HANDLER VectoredHandler; EXCEPTION_POINTERS ExceptionInfo; BOOLEAN Remove = FALSE; BOOLEAN Ret = FALSE; ExceptionInfo.ExceptionRecord = ExceptionRecord; ExceptionInfo.ContextRecord = Context; if(RtlpVectoredExceptionsInstalled) { RtlEnterCriticalSection(&RtlpVectoredExceptionLock); CurrentEntry = RtlpVectoredExceptionHead.Flink; while (CurrentEntry != &RtlpVectoredExceptionHead) { veh = CONTAINING_RECORD(CurrentEntry, RTL_VECTORED_EXCEPTION_HANDLER, ListEntry); veh->Refs++; RtlLeaveCriticalSection(&RtlpVectoredExceptionLock); VectoredHandler = RtlDecodePointer(veh->VectoredHandler); if(VectoredHandler(&ExceptionInfo) == EXCEPTION_CONTINUE_EXECUTION) { RtlEnterCriticalSection(&RtlpVectoredExceptionLock); if (--veh->Refs == 0) { RemoveEntryList (&veh->ListEntry); InterlockedDecrement (&RtlpVectoredExceptionsInstalled); Remove = TRUE; } Ret = TRUE; break; } RtlEnterCriticalSection(&RtlpVectoredExceptionLock); if (--veh->Refs == 0) { CurrentEntry = veh->ListEntry.Flink; RemoveEntryList (&veh->ListEntry); InterlockedDecrement (&RtlpVectoredExceptionsInstalled); RtlLeaveCriticalSection(&RtlpVectoredExceptionLock); RtlFreeHeap(RtlGetProcessHeap(), 0, veh); RtlEnterCriticalSection(&RtlpVectoredExceptionLock); } else CurrentEntry = CurrentEntry->Flink; } RtlLeaveCriticalSection(&RtlpVectoredExceptionLock); } if (Remove) { RtlFreeHeap(RtlGetProcessHeap(), 0, veh); } return Ret; }