/* Report as a non-fatal error.
Print the system error message only if the message is non-null. */
{
if (lstrlen (UserMessage) > 0)
ReportError (UserMessage, 0, TRUE);
/* If fatal, raise an exception. */
/* Categorize the exception and decide whether to continue execution or
execute the handler or to continue the search for a handler that
can process this exception type. The exception category is only used
by the exception handler. */
{
DWORD ExCode;
DWORD_PTR ReadWrite, VirtAddr;
ExCode = pExP->ExceptionRecord->ExceptionCode;
_tprintf (_T ("Filter. ExCode: %x\n"), ExCode);
if ((0x20000000 & ExCode) != 0) {
/* User Exception. */
*ECatgry = 10;
return EXCEPTION_EXECUTE_HANDLER;
}
switch (ExCode) {
case EXCEPTION_ACCESS_VIOLATION:
/* Determine whether it was a read or write
and give the virtual address. */
ReadWrite =
pExP->ExceptionRecord->ExceptionInformation [0];
VirtAddr =
pExP->ExceptionRecord->ExceptionInformation [1];
_tprintf
("Access Violation. Read/Write: %d. Address: %x\n",
ReadWrite, VirtAddr);
*ECatgry = 1;
return EXCEPTION_EXECUTE_HANDLER;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
*ECatgry = 1;
return EXCEPTION_EXECUTE_HANDLER;
/* Integer arithmetic exception. Halt execution. */
case EXCEPTION_INT_DIVIDE_BY_ZERO:
case EXCEPTION_INT_OVERFLOW:
*ECatgry = 2;
return EXCEPTION_EXECUTE_HANDLER;
/* Float exception. Attempt to continue execution. */
/* Return the maximum floating value. */
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
case EXCEPTION_FLT_OVERFLOW:
_tprintf (_T ("Flt Exception - Large result.\n"));
*ECatgry = 3;
_clearfp();
return (DWORD) EXCEPTION_EXECUTE_HANDLER;
case EXCEPTION_FLT_DENORMAL_OPERAND:
case EXCEPTION_FLT_INEXACT_RESULT:
case EXCEPTION_FLT_INVALID_OPERATION:
case EXCEPTION_FLT_STACK_CHECK:
_tprintf (_T ("Flt Exception - Unknown result.\n"));
*ECatgry = 3;
return (DWORD) EXCEPTION_CONTINUE_EXECUTION;
/* Return the minimum floating value. */
case EXCEPTION_FLT_UNDERFLOW:
_tprintf (_T ("Flt Exception - Small result.\n"));
*ECatgry = 3;
return (DWORD) EXCEPTION_CONTINUE_EXECUTION;
case EXCEPTION_DATATYPE_MISALIGNMENT:
*ECatgry = 4;
return EXCEPTION_CONTINUE_SEARCH;
case STATUS_NONCONTINUABLE_EXCEPTION:
*ECatgry = 5;
return EXCEPTION_EXECUTE_HANDLER;
case EXCEPTION_ILLEGAL_INSTRUCTION:
case EXCEPTION_PRIV_INSTRUCTION:
*ECatgry = 6;
return EXCEPTION_EXECUTE_HANDLER;
case STATUS_NO_MEMORY:
*ECatgry = 7;
return EXCEPTION_EXECUTE_HANDLER;
default:
*ECatgry = 0;
return EXCEPTION_CONTINUE_SEARCH;
}
}
int _tmain (int argc, LPTSTR argv [])
{
DWORD ECatgry;
BOOL Done = FALSE;
...
while (!Done) __try {
... __try { /* Try-Except block. */
... __leave ... } /* End of inner __try. */
__except (Filter (GetExceptionInformation (), &ECatgry)){
switch (ECatgry) {
case 0: _tprintf (_T ("Unknown exception.\n"));
break;
case 1: _tprintf (_T ("Memory ref exception.\n"));
break;
case 2: _tprintf (_T ("Integer arithmetic exception.\n"));
break;
case 3:
_tprintf (_T ("floating-point exception.\n"));
break;
case 10: _tprintf (_T ("User generated exception.\n"));
break;
default: _tprintf (_T ("Unknown exception.\n"));
break;
}
_tprintf (_T ("End of handler.\n")); } /* End of inner __try __except block. */
switch (CntrlEvent) {
/* The signal timing will determine if you see the second handler message */
case CTRL_C_EVENT:
_tprintf (_T ("Ctrl-c received by handler. Leaving in 10 seconds\n"));
Sleep (4000); /* Decrease this time to get a different effect */
_tprintf (_T ("Leaving handler in 6 seconds.\n"));
Sleep (6000); /* Also try decreasing this time */
return TRUE; /* TRUE indicates that the signal was handled. */
case CTRL_CLOSE_EVENT:
_tprintf (_T ("Leaving the handler in 10 seconds.\n"));
Sleep (4000); /* Decrease this time to get a different effect */
_tprintf (_T ("Leaving handler in 6 seconds.\n"));
Sleep (6000); /* Also try decreasing this time */
return TRUE; /* Try returning FALSE. Any difference? */
default:
_tprintf (_T ("Event: %d. Leaving in 10 seconds\n"), CntrlEvent);
Sleep (4000); /* Decrease this time to get a different effect */
_tprintf (_T ("Leaving handler in 6 seconds.\n"));
Sleep (6000); /* Also try decreasing this time */
return TRUE; /* TRUE indicates that the signal was handled. */
}
}
int main(int argc, char* argv[])
{
// {
/* Add an event handler. */
if (!SetConsoleCtrlHandler (Handler, TRUE))
ReportError (_T ("Error setting event handler"), 1, TRUE);
while (!Exit) { /* This flag is detected right after a beep, before a handler exits */
Sleep (4750); /* Beep every 5 seconds; allowing 250 ms of beep time. */
Beep (1000 /* Frequency */, 250 /* Duration */);
}
_tprintf (_T ("Stopping the main program as requested.\n"));
// }
// printf("Hello World!\n");
return 0;
}