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); 
}