The code fragment below shows how to set a handler while the calling thread is executing driver code. In the event of an exception, OS/2 calls the handler function, which jumps back to the point of setjmp().
#define INCL_DOS #include <os2.h> #include <setjmp.h> // this exception registration record extends the OS/2-defined one in BSEXCPT.H // by adding a C jmp_buf at the end struct _regrec { PULONG pNext; PFN pfnHandler; jmp_buf jmp; } typedef struct _regrec REGREC, *PREGREC; // ------------------------------------------------------------------------- // an exception handler function that jumps back to setjmp() ULONG _System DriverHandler( PEXCEPTIONREPORTRECORD p1, PREGREC p2, PCONTEXTRECORD p3, PVOID pv ) { // handle interesting exceptions switch( p1->ExceptionNum ) { case XCPT_ACCESS_VIOLATION: case XCPT_INTEGER_DIVIDE_BY_ZERO: case XCPT_INTEGER_OVERFLOW: case XCPT_PROCESS_TERMINATE: case XCPT_ASYNC_PROCESS_TERMINATE: // setjmp() will return p1->ExceptionNum longjmp(p2)->jmp, p1->ExceptionNum ); } // not interested; system should continue search return XCPT_CONTINUE_SEARCH; }
// ------------------------------------------------------------------------- // example of an exported driver function; return TRUE upon success LONG _System ExportedDriverFunction( PVOID p ) { REGREC regrec; ULONG ulException; LONG lResult; regrec.pfnHandler = (PFN)DriverHandler; DosSetExceptionHandler( (PEXCEPTIONREGISTRATIONRECORD)®rec ); // get thread state; normally rets 0, rets non-zero after longjmp() ulException = setjmp( regrec.jmp ); if( ulException ) { // an exception occurred // clean up here: release memory, semaphores // must check for exiting thread case switch( ulException ) { case XCPT_PROCESS_TERMINATE: case XCPT_ASYNC_PROCESS_TERMINATE: // thread is ending or being terminated DosUnsetExceptionHandler( (PEXCEPTIONREGISTRATIONRECORD)®rec ); DosExit( EXIT_THREAD, 0 ); } WinSetErrorInfo( ... ); lResult = FALSE; goto depart; } // do the work of the exported function here lResult = TRUE; depart: DosUnsetExceptionHandler( (PEXCEPTIONREGISTRATIONRECORD)®rec ); return lResult; }