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

📄 tmclnt.c

📁 wince host 和 target PCI驱动程序
💻 C
字号:
/*
	tmclnt.c

	960615	TR	Created
	960617	TR	Added all the functions
*/

/*----------------------------------------------------------------------------
          SYSTEM INCLUDE FILES
----------------------------------------------------------------------------*/
#define WANTVXDWRAPS
#include <basedef.h>
#include <vmm.h>
#include <vxdwraps.h>
#include <vwin32.h>

/*----------------------------------------------------------------------------
          DRIVER SPECIFIC INCLUDE FILES
----------------------------------------------------------------------------*/
#include "vxstd.h"
#include "vxwin.h"
#include "vxdbg.h"
#include "tmwincom.h"

#include "tmshare.h"
#include "tmman32.h"
#include "tmif.h"
#include "tmclnt.h"
#include "cqueue.h"


STATUS	clntmCreate ( PVOID *ppvObject, PVOID pContainer )
{
	PTMCLNT_MGR_OBJECT	this;
	DWORD	dwIdx;

	if ( *((PTMCLNT_MGR_OBJECT *)ppvObject) )
	{
		this = *((PTMCLNT_MGR_OBJECT *)ppvObject);
	}
	else
	{
		if ( ( this = vxdMalloc ( sizeof ( TMCLNT_MGR_OBJECT ) ) ) == NULL )
		{
			DP(0,"TM:clntmCreate:vxdMalloc:CLNT_MGR_OBJECT:FAIL\n");
			return TM_STATUS ( TMCLNT_ERR_OUTOFMEMORY );
		}
		FlagSet ( this->dwFlags, TMCLNT_MGR_FLAGDYNAMICALLOC );
	}

	this->dwSize = sizeof ( TMCLNT_MGR_OBJECT );
	FlagSet ( this->dwFlags, TMCLNT_MGR_FLAGINITIALIZED );

	// initialize all the client objects
	for  ( dwIdx = 0 ; dwIdx < TMCLNT_CLIENT_COUNT ;dwIdx ++ )
	{
		this->Client[dwIdx].dwFlags = 0;
		this->Client[dwIdx].dwSize = sizeof ( TMCLNT_OBJECT );
		FlagSet ( this->Client[dwIdx].dwFlags, TMCLNT_FLAGINITIALIZED );
	}	
	*((PTMCLNT_MGR_OBJECT *)ppvObject) = this;
	return TMOK;
}
/*
	clntmOpen
	This calls crates a new instance of client object. The structure 
	PTMCLNT_CLIENT is filled up the caller with the attributes about the 
	client, whcih can be a VxD, 16 bit DLL or 32 bit DLL. Depending upon the
	type of client this call allocates data structures and returns the object
	and handles in the TMCLNT_CLIENT data structure.
*/

STATUS	clntmCreateClnt ( PVOID pvObject, PVOID pvClientInfo, PDWORD pdwHandle  )
{
	PTMCLNT_MGR_OBJECT	this = (PTMCLNT_MGR_OBJECT)pvObject;
	PTMCLNT_CLIENT	pClientInfo = (PTMCLNT_CLIENT)pvClientInfo;

	PTMCLNT_OBJECT		pClient;
	DWORD				dwIdx;

	// initialize all the client objects
	for  ( pClient = NULL, dwIdx = 0 ; dwIdx < TMCLNT_CLIENT_COUNT; dwIdx ++ )
	{
		if ( ! FlagGet ( this->Client[dwIdx].dwFlags, TMCLNT_FLAGALLOCATED ) )
		{	
			pClient = &this->Client[dwIdx];
			break;
		}
	}	

	if ( ! pClient )
	{
		return (TM_STATUS ( TMCLNT_ERR_OUTOFMEMORY ) );
	}
	FlagSet ( pClient->dwFlags, TMCLNT_FLAGALLOCATED );

	// don't use any other field of pClient until we have copied all the
	// data there


	switch ( pClientInfo->dwType )
	{
		case TMCLNT_CLIENT_TYPEDLL32 :
		if ( ( pClientInfo->Client.DLL32.pvOverlappedObject = 
			vxdMalloc  ( sizeof ( OVERLAPPED ) ) ) == NULL )
		{
			DP(0,"TM:clntmOpen:vxdMalloc:pvOverlappedObject:FAIL\n");
			return TM_STATUS( TMCLNT_ERR_OVERLAPPEDALLCOATIONFAIL );
		}
		DP(0,"TM:clntmCreateClnt:pClient[%x]:Idx[%x]:pvOverlappedObject[%x]\n",
			pClient, 
			dwIdx,
			pClientInfo->Client.DLL32.pvOverlappedObject);

		// we want the cqueue object to be allocated dynamically
		pClientInfo->Client.DLL32.pvAdvisoryQueue = NULL;

		// create the advisory request in Ring 0, this queue can be acccessed
		// form ring 0 also.
		if ( cqueueCreate ( TMIF_ADVISORY_REQUEST_COUNT, 
				sizeof ( TMIF_ADVISORY_REQUEST ), NULL, 
				&pClientInfo->Client.DLL32.pvAdvisoryQueue ) != TRUE )
		{
			DP(0,"TM:clntmOpen:vxdMalloc:pvAdvisoryQueue:FAIL\n");
			return TM_STATUS( TMCLNT_ERR_ADVISORYQCREATEFAIL );
		}

		break;

		case TMCLNT_CLIENT_TYPEDLL16 :
		break;

		case TMCLNT_CLIENT_TYPEVXD :
		break;
	}

	// copy the client info object into the client object
	pClient->Client = *pClientInfo;
	pClient->fRing3ThreadActive = FALSE;
	pClient->dwReferenceCount = 0;

	*pdwHandle = (DWORD)pClient;
	return TMOK;


}

STATUS	clntDestroy ( DWORD dwHandle )
{
	PTMCLNT_OBJECT		this = ( PTMCLNT_OBJECT)dwHandle;


	DP(13,"TM:clntDestroy:pClient[%x]:VMHandle[%x]:pvOverlappedObject[%x]\n",
			this, 
			this->Client.Client.DLL32.dwVMHandle,
			this->Client.Client.DLL32.pvOverlappedObject);
	
	if ( ! FlagGet ( this->dwFlags, TMCLNT_FLAGALLOCATED ) )
	{
		DP(0,"TM:clntDestroy:pClient[%x]:INVALID\n",	this );
		return TM_STATUS ( TMCLNT_ERR_INVALIDCLIENT );
	}

	if ( this->dwReferenceCount-- )
	{
		DP(0,"TM:clntDestroy:pClient[%x]:CANNOT FREE RESOURCES:ReferenceCount[%x]\n",
			this, 
			this->dwReferenceCount );
		return TM_STATUS (TMCLNT_ERR_REFERENCESEXIST );
	}

	switch ( this->Client.dwType )
	{
		case TMCLNT_CLIENT_TYPEDLL32 :
		vxdFree ( this->Client.Client.DLL32.pvOverlappedObject );
		cqueueDestroy ( this->Client.Client.DLL32.pvAdvisoryQueue );
		break;

		case TMCLNT_CLIENT_TYPEDLL16 :
		break;

		case TMCLNT_CLIENT_TYPEVXD :
		break;
	}

	FlagClr( this->dwFlags, TMCLNT_FLAGALLOCATED );

	return  TMOK;
}

STATUS	clntIncrementReference ( DWORD dwHandle )
{
	PTMCLNT_OBJECT		this = ( PTMCLNT_OBJECT)dwHandle;
	this->dwReferenceCount++;
	return TMOK;
}

STATUS	clntDecrementReference ( DWORD dwHandle )
{
	PTMCLNT_OBJECT		this = ( PTMCLNT_OBJECT)dwHandle;
	if ( this->dwReferenceCount ) this->dwReferenceCount--;
	return TMOK;
}

STATUS	clntAdvise  ( DWORD dwHandle , PVOID pvAdvisoryObject )
{
	PTMCLNT_OBJECT		this = ( PTMCLNT_OBJECT)dwHandle;
	PTMIF_ADVISORY_REQUEST pAdvisoryObject = 
		(PTMIF_ADVISORY_REQUEST)pvAdvisoryObject;
	DWORD QueueLength;
	switch ( this->Client.dwType )
	{
		case TMCLNT_CLIENT_TYPEDLL32 :
		QueueLength = cqueueLength(this->Client.Client.DLL32.pvAdvisoryQueue);

		if ( QueueLength > 10 )
		{
			DP ( 0,"[UK:%x]", QueueLength );
		}

		if ( cqueueInsert ( 
			this->Client.Client.DLL32.pvAdvisoryQueue, 
			pAdvisoryObject ) !=  TRUE )
		{
			return TM_STATUS ( TMCLNT_ERR_ADVISORYQFULL );
		}

		if ( ! this->fRing3ThreadActive )
		{
			this->fRing3ThreadActive = TRUE;
			winVWIN32_DIOCCompletionRoutine ( 
				((OVERLAPPED *)this->Client.Client.DLL32.pvOverlappedObject)->O_Internal );
		}
		break;

		case TMCLNT_CLIENT_TYPEDLL16 :
		/*
		( this->Client.Client.DLL16.CallbackFunc ) ( pAdvisoryObject, 
			this->Client.dwContext );
		*/
		break;

		case TMCLNT_CLIENT_TYPEVXD :
		((TMMAN_ADVISORY_NOTIFICATION)pAdvisoryObject->dwCallback )(
			pAdvisoryObject->dwMessage,
			pAdvisoryObject->dwObjHandle,
			pAdvisoryObject->pContext,
			&pAdvisoryObject->Packet );
		break;
	}

	return TMOK;

}

/*
	clntWaitForAdvise

	called by TMIF_BLOCKONADVISE.
	This devioctl is passed only by 32 bit clients that have a worker thread
	processing requests out of the advisory request queue. The client makes 
	this call when he thinks that there are no more requests in the queue. At
	this call the clients thread blocks on the overlapped event. So from this
	point onwards it is ready to process more requests. To be on the safe side
	this function rechecks the request queue and resignals the event if there 
	are requests to be processed.

*/

STATUS	clntWaitForAdvise ( DWORD dwHandle )
{
	PTMCLNT_OBJECT		this = ( PTMCLNT_OBJECT)dwHandle;

	// verify that client is of the right type
	switch ( this->Client.dwType )
	{
		case TMCLNT_CLIENT_TYPEDLL32 :
		this->fRing3ThreadActive = FALSE;

		if ( ! cqueueIsEmpty ( this->Client.Client.DLL32.pvAdvisoryQueue ) )
		{
			this->fRing3ThreadActive = TRUE;
			winVWIN32_DIOCCompletionRoutine ( 
				((OVERLAPPED *)this->Client.Client.DLL32.pvOverlappedObject)->O_Internal );
		}
		break;

		default :
		return ( TM_STATUS ( TMCLNT_ERR_INVALIDCLIENT ) );
		break;
	}
} 

STATUS	clntmDestroy ( PVOID pvObject )
{
	PTMCLNT_MGR_OBJECT	this = (PTMCLNT_MGR_OBJECT)pvObject;

	this->dwSize = 0;

	if ( FlagGet ( this->dwFlags, TMCLNT_MGR_FLAGDYNAMICALLOC ) )
	{
		this->dwFlags = 0;
		vxdFree ( this );		
	}
	else
	{
		this->dwFlags = 0;
	}
	return TMOK;
}

STATUS	clntmVMHandleToClnt ( PVOID pObject, DWORD VMHandle, 
	PDWORD pClientHandle )
{
	PTMCLNT_MGR_OBJECT	this = (PTMCLNT_MGR_OBJECT)pObject;
	DWORD Idx;
	PTMCLNT_OBJECT pClient;

	for  ( Idx = 0 ; Idx < TMCLNT_CLIENT_COUNT ;Idx ++ )
	{
		pClient = &this->Client[Idx];

		DP(13,"TM:clntmVMHandleToClnt:pClient[%x]:Idx[%x]:VMHandle[%x]\n",
			pClient, 
			Idx,
			VMHandle);

		if ( ! FlagGet ( pClient->dwFlags, TMCLNT_FLAGALLOCATED ) )
			continue;
		if ( pClient->Client.dwType != TMCLNT_CLIENT_TYPEDLL32 )  
			continue;
		switch ( pClient->Client.dwType )
		{
			case	TMCLNT_CLIENT_TYPEDLL32	:
			if ( pClient->Client.Client.DLL32.dwVMHandle == VMHandle )
			{
				*pClientHandle = (DWORD)pClient;
				return TMOK;
			}
			break;

			case	TMCLNT_CLIENT_TYPEDLL16	:
			case	TMCLNT_CLIENT_TYPEVXD	:
			return TMCLNT_ERR_CLIENTSYSVM;
			break;
		}
	}	
	
	return TMCLNT_ERR_VMNOTREGISTERED;
}

⌨️ 快捷键说明

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