Doxygen

Definition at line 236 of file except.c.

Referenced by __declspec(), BaseExceptionFilter(), and BaseThreadExceptionFilter().

{
   LONG RetValue;
   HANDLE DebugPort = NULL;
   NTSTATUS ErrCode;
   ULONG_PTR ErrorParameters[4];
   ULONG ErrorResponse;
   PEXCEPTION_RECORD ExceptionRecord = ExceptionInfo->ExceptionRecord;
   LPTOP_LEVEL_EXCEPTION_FILTER RealFilter;

   if ((NTSTATUS)ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION &&
       ExceptionRecord->NumberParameters >= 2)
   {
      switch(ExceptionRecord->ExceptionInformation[0])
      {
      case EXCEPTION_WRITE_FAULT:
         /* Change the protection on some write attempts, some InstallShield setups
            have this bug */
         RetValue = BasepCheckForReadOnlyResource(
            (PVOID)ExceptionRecord->ExceptionInformation[1]);
         if (RetValue == EXCEPTION_CONTINUE_EXECUTION)
            return EXCEPTION_CONTINUE_EXECUTION;
         break;
      case EXCEPTION_EXECUTE_FAULT:
         /* FIXME */
         break;
      }
   }

   /* Is there a debugger running ? */
   ErrCode = NtQueryInformationProcess(NtCurrentProcess(), ProcessDebugPort,
                                       &DebugPort, sizeof(HANDLE), NULL);
   if (!NT_SUCCESS(ErrCode) && ErrCode != STATUS_NOT_IMPLEMENTED)
   {
      BaseSetLastNTError(ErrCode);
      return EXCEPTION_EXECUTE_HANDLER;
   }

   if (DebugPort)
   {
      /* Pass the exception to debugger. */
      DPRINT("Passing exception to debugger\n");
      return EXCEPTION_CONTINUE_SEARCH;
   }

   RealFilter = RtlDecodePointer(GlobalTopLevelExceptionFilter);
   if (RealFilter)
   {
      LONG ret = RealFilter(ExceptionInfo);
      if (ret != EXCEPTION_CONTINUE_SEARCH)
         return ret;
   }

   if ((GetErrorMode() & SEM_NOGPFAULTERRORBOX) == 0)
      PrintStackTrace(ExceptionInfo);

   /* Save exception code and address */
   ErrorParameters[0] = (ULONG)ExceptionRecord->ExceptionCode;
   ErrorParameters[1] = (ULONG_PTR)ExceptionRecord->ExceptionAddress;

   if ((NTSTATUS)ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION)
   {
       /* get the type of operation that caused the access violation */
       ErrorParameters[2] = ExceptionRecord->ExceptionInformation[0];
   }
   else
   {
       ErrorParameters[2] = ExceptionRecord->ExceptionInformation[2];
   }

   /* Save faulting address */
   ErrorParameters[3] = ExceptionRecord->ExceptionInformation[1];

   /* Raise the harderror */
   ErrCode = NtRaiseHardError(STATUS_UNHANDLED_EXCEPTION,
       4, 0, ErrorParameters, OptionOkCancel, &ErrorResponse);

   if (NT_SUCCESS(ErrCode) && (ErrorResponse == ResponseCancel))
   {
       /* FIXME: Check the result, if the "Cancel" button was
                 clicked run a debugger */
       DPRINT1("Debugging is not implemented yet\n");
   }

   /*
    * Returning EXCEPTION_EXECUTE_HANDLER means that the code in
    * the __except block will be executed. Normally this will end up in a
    * Terminate process.
    */

   return EXCEPTION_EXECUTE_HANDLER;
}