发信人: 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]
|
|