示例#1
0
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;
   }
示例#2
0
文件: vectoreh.c 项目: GYGit/reactos
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;
}
示例#3
0
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;
}