/*
 * Win32 exception functions
 *
 * Copyright (c) 1996 Onno Hovers, (onno@stack.urc.tue.nl)
 *
 * Notes:
 *  What really happens behind the scenes of those new
 *  __try{...}__except(..){....}  and
 *  __try{...}__finally{...}
 *  statements is simply not documented by Microsoft. There could be different
 *  reasons for this: 
 *  One reason could be that they try to hide the fact that exception 
 *  handling in Win32 looks almost the same as in OS/2 2.x.  
 *  Another reason could be that Microsoft does not want others to write
 *  binary compatible implementations of the Win32 API (like us).  
 *
 *  Whatever the reason, THIS SUCKS!! Ensuring portabilty or future 
 *  compatability may be valid reasons to keep some things undocumented. 
 *  But exception handling is so basic to Win32 that it should be 
 *  documented!
 *
 * Fixmes:
 *  -Most functions need better parameter checking.
 *  -I do not know how to handle exceptions within an exception handler.
 *   or what is done when ExceptionNestedException is returned from an 
 *   exception handler
 *  -Real exceptions are not yet implemented. only the exception functions
 *   are implemented. A real implementation needs some new code in
 *   loader/signal.c. There would also be a need for showing debugging
 *   information in UnhandledExceptionFilter.
 *
 */
#ifndef WINELIB

#include <stdio.h>
#include "windows.h"
#include "winerror.h"
#include "stddebug.h"
#include "debug.h"
#include "except.h"

LPTOP_LEVEL_EXCEPTION_FILTER pTopExcHandler = NULL;

void EXC_Init(void)
{
    pTopExcHandler = (LPTOP_LEVEL_EXCEPTION_FILTER)GetProcAddress32(
                                                 GetModuleHandle("KERNEL32"),
                                                 "UnhandledExceptionFilter" );
}

/*
 *       EXC_RtlUnwind
 *
 *  This function is undocumented. This is the general idea of 
 *  RtlUnwind, though. Note that error handling is not yet implemented
 *  
 */

void EXC_RtlUnwind(PEXCEPTION_FRAME pEndFrame,LPVOID unusedEip, 
                   PEXCEPTION_RECORD pRecord, DWORD returnEax,
                   PCONTEXT pcontext)
{   
   EXCEPTION_RECORD record;
   DWORD            dispatch;
   int              retval;
  
   pcontext->Eax=returnEax;
   
   /* build an exception record, if we do not have one */
   if(!pRecord)
   {
     record.ExceptionCode=   0xC0000026;  /* invalid disposition */ 
     record.ExceptionFlags=  0;
     record.ExceptionRecord= NULL;
     record.ExceptionAddress=(LPVOID) pcontext->Eip; 
     record.NumberParameters= 0;
     pRecord=&record;     
   }

   if(pEndFrame)
     pRecord->ExceptionFlags|=EH_UNWINDING;
   else
     pRecord->ExceptionFlags|=EH_UNWINDING | EH_EXIT_UNWIND;
  
   /* get chain of exception frames */      
   while((TebExceptionFrame!=NULL)&&
         (TebExceptionFrame!=((void *)-1)) &&
         (TebExceptionFrame!=pEndFrame))
   {
       dprintf_win32(stddeb,"calling exception handler at 0x%x\n",
                                           (int) TebExceptionFrame->Handler);

       dispatch=0;       
       retval=TebExceptionFrame->Handler(pRecord, TebExceptionFrame,
                                         pcontext, &dispatch);
                                         
       dprintf_win32(stddeb,"exception handler returns 0x%x, dispatch=0x%x\n",
                              retval, (int) dispatch);
  
       if(retval==ExceptionCollidedUnwind)
          TebExceptionFrame=(LPVOID) dispatch;
       else if(TebExceptionFrame!=pEndFrame)
          TebExceptionFrame=TebExceptionFrame->Prev;
       else
          break;  
   }
}

/*
 *    EXC_RaiseException
 *
 */
 
VOID EXC_RaiseException(DWORD dwExceptionCode,
		    DWORD dwExceptionFlags,
		    DWORD cArguments,
		    const LPDWORD lpArguments,
		    PCONTEXT pcontext)
{
    PEXCEPTION_FRAME    pframe; 
    EXCEPTION_RECORD    record;
    DWORD               dispatch; /* is this used in raising exceptions ?? */
    int                 retval;
    int                 i;
    
    /* compose an exception record */ 
    
    record.ExceptionCode       = dwExceptionCode;   
    record.ExceptionFlags      = dwExceptionFlags;
    record.ExceptionRecord     = NULL;
    record.NumberParameters    = cArguments;
    record.ExceptionAddress    = (LPVOID) pcontext->Eip;
    
    for(i=0;i<cArguments;i++)
       record.ExceptionInformation[i]=lpArguments[i];
    
    /* get chain of exception frames */    
    
    retval=ExceptionContinueSearch;    
    pframe=TebExceptionFrame;
    
    while((pframe!=NULL)&&(pframe!=((void *)0xFFFFFFFF)))
    {
       dprintf_win32(stddeb,"calling exception handler at 0x%x\n",
                                                (int) pframe->Handler);
       dispatch=0;  
       retval=pframe->Handler(&record,pframe,pcontext,&dispatch);
 
       dprintf_win32(stddeb,"exception handler returns 0x%x, dispatch=0x%x\n",
                              retval, (int) dispatch);
                              
       if(retval==ExceptionContinueExecution)
          break;
       pframe=pframe->Prev;
   }

   if(retval!=ExceptionContinueExecution)
   {    
      retval=EXC_CallUnhandledExceptionFilter(&record,pcontext);
      if(retval!=EXCEPTION_CONTINUE_EXECUTION)
      {
         dprintf_win32(stddeb,"no handler wanted to handle "
                              "the exception, exiting\n"     );
         ExitProcess(dwExceptionCode); /* what status should be used here ? */         
      }                   
   } 
}

/*******************************************************************
 *         UnhandledExceptionFilter (KERNEL32.537)
 * 
 *  This is the unhandled exception code. 
 *  Actually, this should show up a dialog box, with all kinds of
 *  fancy debugging information. It does nothing now!
 */
 
DWORD UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers)
{
   PEXCEPTION_RECORD pRecord;
   PCONTEXT          pContext;
   
   pRecord=epointers->ExceptionRecord;
   pContext=epointers->ContextRecord;
   
   if(pRecord->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND) )
   {
      dprintf_win32(stddeb,"UnhandledExceptionFilter: exiting\n");
      ExitProcess(pRecord->ExceptionCode);            
   }
   else
   {
      RtlUnwind(0,pRecord,0,-1 );
   }
   
   /* 
    * This is just to avoid a warning, code should not get here 
    * if it does, EXC_RaiseException will terminate it. 
    */
   return EXCEPTION_CONTINUE_SEARCH;
}

/*************************************************************
 *    SetUnhandledExceptionFilter    (KERNEL32.516)
 *  
 *
 */
  
LPTOP_LEVEL_EXCEPTION_FILTER 
        SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER efilter)
{  
   pTopExcHandler=efilter;
   return efilter;
}

#endif  /* WINELIB */
