www.pudn.com > GUIhookNT.zip > XCPTREPT.C
#include#include #include #include #include #include #include #include "toolhelp.h" #include "texthook.h" #include "guidll.h" WORD Exception_CS, Exception_DS, Exception_ES, Exception_SS, Exception_SP; void FindExcpTaskName(LPSTR szExcpTaskName ) { TASKENTRY te; te.dwSize = sizeof(te); if ( TaskFindHandle(&te, GetCurrentTask()) ){ strcpy(szExcpTaskName, te.szModule); }else{ szExcpTaskName[0]=0; } return ; } static char sBuf [128]; void DoExceptionReport(int wNumber) { // Post a message to the CORONER window, so it can display the // exception message. FindExcpTaskName(sBuf ); PostMessage(HTextHookWnd, WM_TEXTHOOK_EXCEPTION, wNumber,(LPARAM) sBuf); } char *tempstack; // Pointer to temporary working stack WORD tempstack_end; // offset of the end of the temporary stack WORD old_ss; // A place to save the SS:SP that we came in on. WORD old_sp; WORD exception_number; #pragma argsunuse void C_ExceptionHandler( WORD wES, WORD wDS, WORD wDI, WORD wSI, WORD wBP, WORD wSP, WORD wBX, WORD wDX, WORD wCX, WORD wAX, WORD wOldBP, WORD wRetIP, WORD wRetCS, WORD wRealAX, WORD wNumber, WORD wHandle, WORD wIP, WORD wCS, WORD wFlags) { // Flag that tells us if we're already processing an interrupt/exception static WORD inHandler = 0; /* wES;wDS;wDI;wSI;wBP;wSP;wBX; wDX;wCX;wAX;wOldBP;wRetIP; wRetCS;wRealAX;wNumber;wHandle; wIP;wCS;wFlags; */ // Pass on the debugger interrupts. We don't care about them. if ( (wNumber == 1) || (wNumber == 3) ) return; /* See if we're already here. If so, chain on */ if (inHandler) return; else inHandler = 1; // Save off all of the parameters that we care about. We're going to // be switching stacks, so they won't be available. exception_number = wNumber; asm mov [Exception_SS],ss asm lea ax, [wES + 26h] // calculate SP at time of exception asm mov [Exception_SP],ax // We're now going to switch the stack over to the temporary 4K stack // we allocated before we called InterruptRegister asm { mov [old_ss], ss mov [old_sp], sp mov ax, ds mov ss, ax mov sp, [tempstack_end] } DoExceptionReport(exception_number); // Switch the stack back to the original stack asm { mov ss, [old_ss] mov sp, [old_sp] } inHandler = 0; // Return to .ASM handler, which will chain on to the other installed // handlers. If none of them handle it, Windows will kill the task for us. return; } #define TEMPSTACK_SIZE 4096 BOOL FAR PASCAL _export SetupInterruptHandler(void) { return TRUE ; tempstack = malloc(TEMPSTACK_SIZE); if ( !tempstack ) return 0; tempstack_end = (WORD)((tempstack + TEMPSTACK_SIZE) - 2); return InterruptRegister(NULL, (FARPROC)EXCEPTIONHANDLER); } void FAR PASCAL _export ShutdownInterruptHandler(void) { return ; InterruptUnRegister(NULL); if ( tempstack ) free(tempstack); }