//==================================================
// MYSEH - Matt Pietrek 1997
// Microsoft Systems Journal, January 1997
// FILE: MYSEH.CPP
// To compile: CL MYSEH.CPP
//==================================================
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>

/*#ifdef __MINGW32__*/
#include <excpt.h>

DWORD  scratch;

EXCEPTION_DISPOSITION
#ifdef __MINGW32__
#else
__cdecl
#endif
_except_handler(
    struct _EXCEPTION_RECORD *ExceptionRecord,
    void * EstablisherFrame,
    struct _CONTEXT *ContextRecord,
    void * DispatcherContext )
{
    unsigned i;

    // Indicate that we made it to our exception handler
    printf( "Hello from an exception handler\n" );

    // Change EAX in the context record so that it points to someplace
    // where we can successfully write
    ContextRecord->Eax = (DWORD)&scratch;

    // Tell the OS to restart the faulting instruction
    return ExceptionContinueExecution;
}

int main()
{
    DWORD handler = (DWORD)_except_handler;

#ifndef __MINGW32__
    __asm
    {                           // Build EXCEPTION_REGISTRATION record:
        push    handler         // Address of handler function
        push    FS:[0]          // Address of previous handler
        mov     FS:[0],ESP      // Install new EXECEPTION_REGISTRATION
        mov     eax,0           // Zero out EAX
        mov     [eax], 1        // Write to EAX to deliberately cause a fault
    }
#else
    __asm__ __volatile__ (
             "pushl %0" : /* None */ : "a"(handler));
    __asm__ __volatile__ (
             "pushl %fs:0 \n\t"
             "mov   %esp,%fs:0 \n\t"
             "mov   $0,%eax \n\t"
             "movb  $1,(%eax)");
#endif

    printf( "After writing!\n" );

#ifndef __MINGW32__
    __asm
    {                           // Remove our EXECEPTION_REGISTRATION record
        mov     eax,[ESP]       // Get pointer to previous record
        mov     FS:[0], EAX     // Install previous record
        add     esp, 8          // Clean our EXECEPTION_REGISTRATION off stack
    }
#else
    __asm__ __volatile__ (
             "mov (%esp),%eax \n\t"
             "mov %eax,%fs:0 \n\t"
             "add $8,%esp");

#endif

    return 0;
}


