//*************************************************************** // From the book "Win32 System Services: The Heart of Windows 98 // and Windows 2000" // by Marshall Brain // Published by Prentice Hall // // Copyright 1995, by Prentice Hall. // // This code demonstrates a user-defined exception. //*************************************************************** // softexpt.cpp #include #include #define TYPE_1 0x1 // an ignored exception #define TYPE_2 0x2 // a handled exception #define TYPE_3 0x3 // an unhandled exception VOID MakeException(DWORD type) { switch(type) { // recoverable exeception case TYPE_1: RaiseException(TYPE_1, 0, NULL, NULL); break; // exception which must be handled case TYPE_2: RaiseException(TYPE_2, EXCEPTION_NONCONTINUABLE, NULL, NULL); break; // just generate an exception case TYPE_3: RaiseException(TYPE_3, 0, NULL, NULL); break; } } DWORD Filter(EXCEPTION_POINTERS *ep) { cerr << "Dumping some exception info:" << endl; cerr << "Code : 0x" << hex << ep->ExceptionRecord->ExceptionCode << endl; cerr << "Flags: 0x" << hex << ep->ExceptionRecord->ExceptionFlags << endl; cerr << "Addr : " << hex << ep->ExceptionRecord->ExceptionAddress << endl; // arguments from RaiseException can also // be retrieved from "ep" // decide what to do based on type switch(ep->ExceptionRecord->ExceptionCode) { case TYPE_1: cerr << "Allow execution to continue." << endl; return(EXCEPTION_CONTINUE_EXECUTION); break; case TYPE_2: cerr << "Execute exception handler block." << endl; return(EXCEPTION_EXECUTE_HANDLER); break; case TYPE_3: cerr << "Pass exception to debugger or system." << endl; return(EXCEPTION_CONTINUE_SEARCH); break; default: return(EXCEPTION_EXECUTE_HANDLER); } } VOID TryExcept(DWORD type) { __try { MakeException(type); } __except(Filter(GetExceptionInformation())) { // report the exception type cerr << "Caught exception code: 0x" << hex << GetExceptionCode() << endl; } } // User defined exception filter which // gets dispatched whenever user code // does not handle an exception LONG TopLevelExceptionFilter (EXCEPTION_POINTERS *ep) { // exception information can be used // from "ep" if needed cerr << "Exception filtered by user " << "defined \"Unhandled Exception " << "Filter\"." << endl; Beep(300, 100); MessageBox(NULL, "Managing Exception", "Programmer Defined Filter", MB_OK | MB_ICONINFORMATION); // allow exception handler to execute which // causes program termination return(EXCEPTION_EXECUTE_HANDLER); // use care when returning // EXCEPTION_CONTINUE_EXECUTION // because an infinite loop of // exceptions may occur } VOID main(VOID) { cout << "Generate an exception which " << "can be ignored." << endl; TryExcept(TYPE_1); cout << endl << "Generate an exception which " << "can be handled." << endl; TryExcept(TYPE_2); // Replace system exception filter // with a custom filter SetUnhandledExceptionFilter( (LPTOP_LEVEL_EXCEPTION_FILTER) TopLevelExceptionFilter); // generate an exception which // gets passed out to the newly // defined custom filter cout << endl << "Generate an exception which " << "is not handled." << endl; TryExcept(TYPE_3); }