/*
 * 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 "kernel32.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 */
