//
// EXCEP2.C -- Sample structured exception handler
//             Causes an integer overflow exception, a divide by zero
//             exception, and a GP (general protection) fault
//
#include <stdio.h>
#include <stdlib.h>
#include <pharlap.h>
#define i386 1
#define WIN32
#include <windows.h>
#include <excpt.h>

void CauseExceptions(void);
int ExceptionFilter(ULONG ExcepCode, struct _EXCEPTION_POINTERS *pExcepInfo);

int main()
{
	try
	{
		CauseExceptions();
	}
	except (ExceptionFilter(GetExceptionCode(),GetExceptionInformation()))
	{
		printf("In exception handler:  terminating program\n");
		exit(1);
	}

	printf("Normal termination\n");
	return 0;
}

int VarInDataSeg;
void CauseExceptions(void)
{
	_asm
	{
		mov	eax,7FFFFFFFh
		mov	ebx,7FFFFFFFh
		add	eax,ebx
		into			; integer overflow
	}

	_asm
	{
		xor	ebx,ebx
		div	ebx		; divide by zero
	}

	_asm
	{
		push	0
		pop	ds		; set DS to null selector
		mov	VarInDataSeg,0	; GP fault, because DS is null
	}
	return;
}

int ExceptionFilter(ULONG ExcepCode, struct _EXCEPTION_POINTERS *pExcepInfo)
{
	EXCEPTION_RECORD *pExcepRecord;
	CONTEXT *pContext;

	pExcepRecord = pExcepInfo->ExceptionRecord;
	pContext = pExcepInfo->ContextRecord;

	switch (ExcepCode)
	{
case EXCEPTION_INT_OVERFLOW:	// from INTO, ignore it and continue
		printf("Got integer overflow exception -- ignoring it\n");
		return EXCEPTION_CONTINUE_EXECUTION;

case EXCEPTION_INT_DIVIDE_BY_ZERO: // from DIV instruction
		// Step the EIP past the 2-byte DIV opcode and continue
		printf("Got divide-by-zero exception\n");
		if (!pContext->ContextFlags & CONTEXT_CONTROL)
		{
			printf("  No context -- let system handler run\n");
			return EXCEPTION_CONTINUE_SEARCH;
		}
		printf("  Incrementing EIP past DIV and ignoring it\n");
		pContext->Eip += 2;
		return EXCEPTION_CONTINUE_EXECUTION;

case EXCEPTION_ACCESS_VIOLATION: // from GP fault - execute handler
		printf("Got GP fault -- letting except() handler run\n");
		return EXCEPTION_EXECUTE_HANDLER;

default:	// not an exception this program catches; let default 
		// system handler take it
		printf("Unexpected exception code: %08Xh\n", ExcepCode);
		return EXCEPTION_CONTINUE_SEARCH;
	}
}
