⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 apisrv.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 2 页
字号:
//返回值:
//   假如成功,返回TRUE;否则,返回FALSE
//功能描述:
// 调用_EnterAPI
//引用:系统调用 
// ********************************************************************
BOOL WINAPI KC_EnterAPI( UINT uiAPIId, UINT uiOptionId, VOID * lpfn, CALLSTACK * lpcsRet )
{
	CALLSTACK * lpcall;
	
	// 分配一个调用stack,用于保存系统调用上下文
	lpcall = KHeap_Alloc( sizeof( CALLSTACK ) );
	if( lpcall )
	{
		if( _EnterAPI( uiAPIId, uiOptionId, lpfn, lpcall ) )
		{
			lpcall->dwCallInfo |= MAKE_OPTIONINFO( uiAPIId, uiOptionId );
			*lpcsRet = *lpcall;
			lpcall->dwCallInfo |= CALL_ALLOC;
			return TRUE;
		}
		else
		{
			KHeap_Free( lpcall, sizeof( CALLSTACK ) );
		}
	}
	return FALSE;
}


// ********************************************************************
//声明:DWORD FASTCALL EnumServer( LPSERVER_ENUM_PROC lpEnumFunc, LPVOID lpParam )
//参数:
// IN lpEnumFunc-需要回调的枚举功能
// IN lpParam-传递给lpEnumFunc功能的参数
//返回值:
// 成功返回0
//功能描述:枚举所有已注册的服务,假如lpEnumFunc返回FALSE,则终止继续枚举
//引用: 
// ********************************************************************
BOOL FASTCALL EnumServer( LPSERVER_ENUM_PROC lpEnumFunc, LPVOID lpParam )
{
	int i;
	APIINFO * lpAPI = &apiInfo[MAX_API-1];

    for( i = MAX_API-1; i >= 8; i--, lpAPI-- )
	{
	    if( lpAPI->lpfn && lpAPI->lpServerCtrlInfo )
		{  // valid server
            if( lpEnumFunc( lpAPI, lpParam ) == FALSE )
				return FALSE;
		}
	}
	return TRUE;
}

// ********************************************************************
//声明:DWORD FASTCALL EnumServerHandler( DWORD dwIoCtl, DWORD dwParam, LPVOID lpParam )
//参数:
//	IN dwIoCtl - 需要回调的枚举功能
//	IN dwParam - 传递ServerHandler的dwParam参数
//	IN lpParam - 传递ServerHandler的lpParam参数
//返回值:
//	成功返回0
//功能描述:
//	枚举所有已注册的服务的ServerHandler
//引用: 
// ********************************************************************
DWORD FASTCALL EnumServerHandler( DWORD dwEventCode, DWORD dwParam, LPVOID lpParam )
{
	int i;
	APIINFO * lpAPI = &apiInfo[MAX_API-1];
	CALLSTACK * lpcs = KHeap_Alloc( sizeof( CALLSTACK ) );

    for( i = MAX_API-1; i >= 8; i--, lpAPI-- )
	{
		if( lpAPI->lpfn && lpAPI->lpServerCtrlInfo )
		{  // valid server
			//CALLSTACK cs;
			BOOL  bHandle = TRUE;
			DWORD dwServerInfo = lpAPI->dwServerInfo;

			if( dwServerInfo & (SCI_NOT_HANDLE_PROCESS_EXIT|SCI_NOT_HANDLE_THREAD_EXIT) )
			{	// 不处理线程退出 或 进程退出事件
				if( ( dwEventCode == SCC_BROADCAST_PROCESS_EXIT && 
					(dwServerInfo & SCI_NOT_HANDLE_PROCESS_EXIT) ) ||
					( dwEventCode == SCC_BROADCAST_THREAD_EXIT && 
					(dwServerInfo & SCI_NOT_HANDLE_THREAD_EXIT) ) )
				{
					bHandle = FALSE;
				}
			}
			if( bHandle )
			{				
				if( SwitchToProcess( lpAPI->lpProcess, lpcs ) )
				{
					lpcs->dwCallInfo |= CALL_ALLOC;

					( (PSERVER_HANDLER)lpAPI->lpServerCtrlInfo->pServerHandler )( lpAPI->hServer, dwEventCode, (DWORD)dwParam, lpParam );
					SwitchBackProcess();
				}
			}
		}
	}
	KHeap_Free( lpcs, sizeof( CALLSTACK ) );
	return 0;
}



// ********************************************************************
//声明:PFNVOID APICallReturn( DWORD * lpdwState )
//参数:
//	OUT lpdwState - 输出状态
//返回值:
// 返回 MakeAPICall保存的调用者的返回地址(pfnRetAdress),lpdwState返回CPU状态
//功能描述:调用完服务功能后回退到调用者的上下文
//引用: 
// 被中断或陷阱调用
// ********************************************************************
PFNVOID APICallReturn( DWORD * lpdwState )
{
	CALLSTACK * lpcs = lpCurThread->lpCallStack;
    PFNVOID pfn = lpcs->pfnRetAdress;

//    ASSERT( lpcs );
	*lpdwState = lpcs->dwStatus;

    //切换到调用者的进程空间
    SwitchBackProcess();

	ASSERT( lpcs->dwCallInfo & CALL_ALLOC );
	//释放MakeAPICall分配的CALLSTACK结构指针
	KHeap_Free( lpcs, sizeof( CALLSTACK ) );
	//返回到调用者的地址
	return pfn;
}

static VOID DoLeaveAPI( VOID )
{
	CALLSTACK * lpcs = lpCurThread->lpCallStack;

    //切换到调用者的进程空间
	SwitchBackProcess();
    ASSERT( (lpcs->dwCallInfo & CALL_ALLOC) );
	//释放MakeAPICall分配的CALLSTACK结构指针
	KHeap_Free( lpcs, sizeof( CALLSTACK ) );

	if( iISRActiveCount )
    {   
		INTR_OFF();
        ISR_Handler( ISR_ALL_INTRS );
		INTR_ON();
    }    
}

// ********************************************************************
//声明:void WINAPI KL_LeaveAPI( void )
//参数:无
//返回值:无
//功能描述:调用完服务功能后回退到调用者的上下文
//引用: 系统调用
// ********************************************************************
void WINAPI KL_LeaveAPI( void )
{
	DoLeaveAPI();
}

// ********************************************************************
//声明:PFNVOID DoImplementCallBack4( LPICB * lpicb )
//参数:
//	IN/OUT lpicb - 输出调用模式
//  
//返回值:
//  返回 调用地址
//功能描述:
//	改变当前的 CALLSTACK 结构数据
//	切换到进程,调用进程功能
//引用: 
// 
// ********************************************************************

PFNVOID DoImplementCallBack( LPSYSCALL lpCallInfo )
{
	HANDLE hProcess = ((LPCALLBACKDATA)lpCallInfo->uiArgs[0])->hProcess;
	LPPROCESS lpProcess  = HandleToPtr( hProcess, OBJ_PROCESS );
	PFNVOID pfn = (PFNVOID)((LPCALLBACKDATA)lpCallInfo->uiArgs[0])->lpfn;
	
	if( lpProcess && pfn )
	{	//得到当前的CS结构指针
		UINT uiSave;
		BOOL bSwitchContext;
		CALLSTACK * lpcs = lpCurThread->lpCallStack;		
		
		LockIRQSave( &uiSave );

		// 如果新的进程与线程的当前进程不同,则需要切换进程空间
		if( lpProcess != lpCurThread->lpCurProcess )
		{
			bSwitchContext = TRUE;			
		}
		else
			bSwitchContext = FALSE;
		// 设置CALLSTACK结构
		lpcs->dwCallInfo &= ~CALL_KERNEL;
		lpcs->lpvData = lpCurThread->lpCurProcess;
		// 是否需要做进程上下文切换?
		if( bSwitchContext )
		{	//是
			//装入当前进程的MMU有关数据,无效CACHE。。。
			AccessKey_Add( &lpCurThread->akyAccessKey, lpProcess->akyAccessKey );
			GetMMUContext( lpCurThread, 1, lpProcess );
        }

		UnlockIRQRestore( &uiSave );

		lpCallInfo->uiArgs[0] = ((LPCALLBACKDATA)lpCallInfo->uiArgs[0])->dwArg0;
		lpCallInfo->uiCallMode = GetCPUMode( lpProcess->dwFlags & 0xF );

		return pfn;
	}
	return NULL;
	
}

// ********************************************************************
//声明:BOOL DoImplementCallBackSwitch( HANDLE hProcess )
//参数:
//	IN hProcess - 进程句柄
//  
//返回值:
//	假如成功,返回TRUE;否则,返回FALSE
//功能描述:
//	分配CALLSTACK 结构并 切换到新的进程空间
//引用:
// ********************************************************************


BOOL DoImplementCallBackSwitchTo( HANDLE hProcess )
{
	CALLSTACK * lpcs;
	BOOL bRetv = FALSE;

	lpcs = KHeap_Alloc( sizeof( CALLSTACK ) );
	if( lpcs )
	{
		bRetv = SwitchToProcessByHandle( hProcess, lpcs );
		if( bRetv )
		{
			lpcs->dwCallInfo |= CALL_ALLOC;
		}
		else
			KHeap_Free( lpcs, sizeof( CALLSTACK ) );
	}
	return bRetv;
}

// ********************************************************************
//声明:VOID DoImplementCallBackSwitchBack( VOID )
//参数:
//	无
//  
//返回值:
//	无
//功能描述:
//	切换回进程空间
//引用:
// ********************************************************************


VOID DoImplementCallBackSwitchBack(VOID)
{
	DoLeaveAPI();
}

// ********************************************************************
//声明:PFNVOID MakeSysCall( LPSYSCALL lpCall )
//参数:
// IN lpCall-包含有系统调用信息的结构指针
//返回值:
// 假如成功,返回服务功能对应的功能地址(也可以为NULL); 否则返回NULL
//功能描述:
// 该函数通常是在系统中断里调用。
// 当用户调用一个服务功能时,会产生一个系统API调用中断(或陷阱)并将服务调用信息传给中断。
// 该中断将调用信息及传递的参数列表传给该函数,并由该函数决定是什么服务调用,
// 切换到服务进程空间,转化相关的参数。最后,返回需要调用的服务功能地址
//引用: 
// 被中断或陷阱调用
// ********************************************************************

#define DEBUG_MAKE_SYS_CALL 0
PFNVOID MakeSysCall( LPSYSCALL lpCallInfo )
{
	UINT dwCallInfo = lpCallInfo->dwCallInfo;
	LPDWORD lpdwCallSP = (LPDWORD)lpCallInfo->uiArgs;
	UINT uiAPIId = (dwCallInfo & APIID_MASK) >> APIID_SHIFT;
	UINT uiOptionId = (dwCallInfo & OPTION_MASK) >> OPTION_SHIFT;
	int  iArgs = (dwCallInfo & ARG_NUM_MASK) >> ARG_NUM_SHIFT;
	PFNVOID pfn;
	CALLSTACK * lpcs;
	
	BOOL bRetv;

    DEBUGMSG( DEBUG_MAKE_SYS_CALL, ( "MakeSysCall:dwCallInfo=0x%x,lpdwCallSP=0x%x,pfnRetAdress=0x%x,uiAPIId=%d,uiOptionId=%d.\r\n", dwCallInfo, lpCallInfo->uiArgs, lpCallInfo->pfnRetAdress, uiAPIId, uiOptionId ) );

	pfn = 0; 
	// 分配一个调用stack,用于保存系统调用上下文
	lpcs = KHeap_Alloc( sizeof( CALLSTACK ) );
//	ASSERT( lpcs );

	if( lpcs && uiOptionId )
	{   //判断是否是基于句柄的服务调用
		if( IS_HANDLE_API( dwCallInfo ) )  // the first args in lpdwCallSP is a handle
		{   //是,得到调用函数地址并做相关的进程切换
			if( ( *lpdwCallSP = (DWORD)HandleToPtr( (HANDLE)*lpdwCallSP, -1 ) ) )
			{
				bRetv = _EnterAPI( uiAPIId, uiOptionId, &pfn, lpcs );
			}
			else
			{
				WARNMSG( DEBUG_MAKE_SYS_CALL, ( "error in MakeAPICall: invalid handle.\r\n" ) );
				bRetv = FALSE;
			}
		}
		else
		{   //得到调用函数地址并做相关的进程切换
			bRetv = _EnterAPI( uiAPIId, uiOptionId, &pfn, lpcs );
		}
		
		if( bRetv )
		{   // 转换调用者传递的参数
			
			DWORD dwArg = apiInfo[uiAPIId].lpArgs[uiOptionId];
			//RETAILMSG( 1, ( "api:0x%x.\r\n", ((LPPROCESS)lpcs->lpvData)->dwVirtualAddressBase ) );
			
			if( uiAPIId > API_KERNEL )
			{
				for( ; dwArg; dwArg >>= 2 )
				{
					if( (dwArg & ARG_MASK) == ARG_PTR )
					{   //如果是指针,重新映射它
						*lpdwCallSP = (DWORD)MapProcessPtr( (LPVOID)*lpdwCallSP, (LPPROCESS)lpcs->lpvData );
					}
					lpdwCallSP++;
					iArgs--;
					DEBUGMSG( !(iArgs >= 0), ( "error (iArgs < 0 !) in MakeAPICall: dwArg(0x%x),uiAPIId(%d),uiOptionId(%d),dwCallInfo(0x%x),ArgNum(%d).\r\n", apiInfo[uiAPIId].lpArgs[uiOptionId], uiAPIId, uiOptionId, dwCallInfo, (dwCallInfo & ARG_NUM_MASK) >> ARG_NUM_SHIFT )  );
				}
			}
			//保存调用者的返回地址
			lpcs->pfnRetAdress = lpCallInfo->pfnRetAdress;
		}
		else
		{
			OutErrorAPIInfo( uiAPIId, uiOptionId );
		}
		
		if( !bRetv )
		{   //假如不成功,做清除工作
			KHeap_Free( lpcs, sizeof( CALLSTACK ) );
		}
		else
		{   // 成功,保存相关信息,CALL_ALLOC代表lpcs是动态分配的,在随后应该调用
			// KHeap_Free去清除它
			lpcs->dwCallInfo |= dwCallInfo | CALL_ALLOC;
			lpcs->dwStatus = lpCallInfo->uiCallMode;
			//返回CPU模式
			lpCallInfo->uiCallMode = GetCPUMode( apiInfo[uiAPIId].lpProcess->dwFlags & 0xF );
		}
	}
	else
	{		
		if( lpcs )
		{
			KHeap_Free( lpcs, sizeof( CALLSTACK ) );
		}
		ERRORMSG( DEBUG_MAKE_SYS_CALL, ( "error in MakeSysCall :lpcs(0x%x), uiOptionId(0x%x).\r\n", lpcs, uiOptionId ) );
	}

	return pfn;
}

int __CheckAPIHeap( UINT uiAPIId, char * lpFile, int line )
{
	return 1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -