发信人: riffle() 
整理人: wenbobo(2002-08-13 10:45:45), 站内信件
 | 
 
 
/* author : *** */
 /*-------------------------------------------------------------------- --*/
 
 // TSRFRAME.CPP
 //本模块和INTFRAME.ASM一起做一个project,在large或huge模式下编译成LIB。 
 
 #include <DOS.H>
 #include <STDIO.H>
 #include <STDLIB.H>
 #include <PROCESS.H>
 #include "INTFRAME.H"
 
 /*-------------------------------------------------------------------- --*/
 
 extern "C"
 {
 extern void SetVectorI( int VerctorNum, void far *FunPtr );
 }
 
 /*-------------------------------------------------------------------- --*/
 
 const int MAXCANEXITCALLBACK = 16;
 static unsigned int CanExitCallBackRegisterPtr = 0;
 static int ( *CanExitCallBack[ MAXCANEXITCALLBACK ] )( void ) =
 	{ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 	  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
 
 /*-------------------------------------------------------------------- --*/
 
 static void InitExitTSR( void );
 static int TsrCanExit( void );
 
 /*-------------------------------------------------------------------- --*/
 /********************************************************************* ***/
 static void InitExitTSR( void )
 {
   unsigned int *Exe22Int;
   union REGS regs;
   struct SREGS sregs;
   unsigned int uiReturnSeg = FP_SEG( GetIntReturnAddr() );
   unsigned int uiReturnOfs = FP_OFF( GetIntReturnAddr() );
 
   // 设置PSP中INT 22的地址为GetIntReturnAddr(),即TSR程序返回DOS之前先 到
   // GetIntReturnAddr()
   // PSP 段地址偏移 0X0A 处存放该进程返回DOS时的返回地址。程序执行exit 命
   // 令时最终将转向此处,这是INT 21内核规定的。
   // 这里取的是中断服务程序中IRET指令前面的地址。
   // 这样,当调用软中断使整个驻留程序退出时,DOS在完成关闭该进程所有打 开
   // 的文件,释放它所占用的内存,等等所有清理工作之后,最后返回到此处, 然
   // 后恢复各个寄存器,最后IRET,就象执行一个普通的软中断一样。
   Exe22Int = ( unsigned int * )MK_FP( _psp, 0x0a );
   Exe22Int[ 0 ] = uiReturnOfs;
   Exe22Int[ 1 ] = uiReturnSeg;
 
   // 设置INT 22、23、24中断向量是为了安全起见。
   // 设置中断向量INT 22
   regs.h.ah = 0x25;
   regs.h.al = 0x22;
   regs.x.dx = uiReturnOfs;
   sregs.ds = uiReturnSeg;
   intdosx( ®s, ®s, &sregs );
 
   // 设置中断向量INT 23
   regs.h.ah = 0x25;
   regs.h.al = 0x23;
   regs.x.dx = uiReturnOfs;
   sregs.ds = uiReturnSeg;
   intdosx( ®s, ®s, &sregs );
 }
 /********************************************************************* ***/
 
 /********************************************************************* ***/
 static int TsrCanExit( void )
 {
   // 反向逐个调用已经登记的驻留退出检查函数,各驻留退出检查函数返回1表 
   // 示可以退出驻留,否则不能退出驻留。
   for( int i = CanExitCallBackRegisterPtr - 1; i >= 0; i-- )
     if ( CanExitCallBack[ i ] != NULL )
       if ( !CanExitCallBack[ i ]() )
         // 有一个函数表明不能退出驻留,则返回0,表示不能退出驻留。
 	return 0;
 
   // 所有检查函数都表示能退出驻留则返回1,表示可以退出驻留。
   return 1;
 }
 /********************************************************************* ***/
 
 /********************************************************************* ***/
 int PrepareExitTSR( void )
 {
   检查是否能退出驻留
   if ( TsrCanExit() )
     {
       // 取当前的PSP
       SaveCurPSP();
       // 设置TSR的返回地址
       InitExitTSR();
       // 将PSP设置成TSR的PSP
       SetPSP( _psp );
       // 返回1,表示可以退出驻留。
       return 1;
     }
   else
     // 否则返回0,表示不能退出驻留。
     return 0;
 }
 /********************************************************************* ***/
 
 /********************************************************************* ***/
 int RegisterExitCallBack( int ( *ExitCallBack )( void ) )
 {
   // 以栈的方式(后进先出)登记退出检查函数。
   if ( CanExitCallBackRegisterPtr < MAXCANEXITCALLBACK )
     {
       CanExitCallBack[ CanExitCallBackRegisterPtr ] = ExitCallBack;
       CanExitCallBackRegisterPtr++;
       // 登记成功,返回1。
       return 1;
     }
   else
     // 登记失败,返回0。
     return 0;
 }
 /********************************************************************* ***/
 
 /********************************************************************* ***/
 void SetVector( int VerctorNum, void far *FunPtr )
 {
   设置中断向量及回调函数。
   SetVectorI( VerctorNum, FunPtr );
 }
 /********************************************************************* ***/
 /********************************************************************* ***/
 /********************************************************************* ***/
  -- ※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.104.39.56]
  | 
 
 
 |