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

📄 tspi.cpp

📁 pppoe client
💻 CPP
📖 第 1 页 / 共 3 页
字号:

//********************************************************************
//	日期:	2004/08/14 - 14:8:2004   10:20
//	名前:	tiamo
//	描述:	tspi http://www.rainyjay.com/tapi/tapi.htm
//*********************************************************************

#include "Stdafx.h"

// reference adapter
VOID ReferenceTspiProvider(PADAPTER pAdapter,BOOLEAN bAcquireSpinLock)
{
	if(bAcquireSpinLock)
		NdisAcquireSpinLock(&pAdapter->m_lockSelf);

	pAdapter->m_lProviderRefCount ++;

	if(bAcquireSpinLock)
		NdisReleaseSpinLock(&pAdapter->m_lockSelf);
}

// dereference adapter
VOID DereferenceTspiProvider(PADAPTER pAdapter)
{
	NdisAcquireSpinLock(&pAdapter->m_lockSelf);

	LONG lCount = --pAdapter->m_lProviderRefCount;
	if(!lCount)
	{
		pAdapter->m_ulProviderFlags &= ~(PROVIDER_INITIALIZED | PROVIDER_SHUTDOWNING);
		pAdapter->m_ulProviderFlags |= PROVIDER_FREEING;
	}

	NdisReleaseSpinLock(&pAdapter->m_lockSelf);

	if(!lCount)
		TspiShutdownComplete(pAdapter);
}

// provider shutdown complete
VOID TspiShutdownComplete(PADAPTER pAdapter)
{
	if(pAdapter->m_ulProviderFlags & PROVIDER_SHUTDOWN_RETURN_PENDING)
		NdisMSetInformationComplete(pAdapter->m_hMiniportAdapter,NDIS_STATUS_SUCCESS);

	TspiCleanup(pAdapter);

	DereferenceAdapter(pAdapter);
}

// call state chage
VOID TspiCallStateChange(PCALL_INFO pCall,ULONG ulState,ULONG ulParam)
{
	if(!pCall)
		return;

	NdisAcquireSpinLock(&pCall->m_lockSelf);
	if(!pCall->m_htCall)
	{
		NdisReleaseSpinLock(&pCall->m_lockSelf);
		return;
	}

	if( ulState == LINECALLSTATE_CONNECTED && 
		pCall->m_ulCallState != LINECALLSTATE_OFFERING &&
		pCall->m_ulCallState != LINECALLSTATE_PROCEEDING)
	{
		NdisReleaseSpinLock(&pCall->m_lockSelf);
		return;
	}

	if(ulState != pCall->m_ulCallState)
	{
		pCall->m_ulCallState = ulState;

		NDIS_TAPI_EVENT evTapi;
		evTapi.htCall = pCall->m_htCall;
		evTapi.htLine = pCall->m_pLine->m_htLine;
		evTapi.ulMsg = LINE_CALLSTATE;
		evTapi.ulParam1 = ulState;
		evTapi.ulParam2 = ulParam;
		evTapi.ulParam3 = LINECALLSTATE_CONNECTED;

		if(ulState == LINECALLSTATE_CONNECTED)
		{
			pCall->m_ulFlags &= ~CALL_CONNECTING;

			pCall->m_wanLinkInfo.HeaderPadding = g_pAdapter->m_wanInfo.HeaderPadding;
			pCall->m_wanLinkInfo.TailPadding = g_pAdapter->m_wanInfo.TailPadding;
			pCall->m_wanLinkInfo.MaxRecvFrameSize = pCall->m_ulMaxFrameSize;
			pCall->m_wanLinkInfo.MaxSendFrameSize = pCall->m_ulMaxFrameSize;
			pCall->m_wanLinkInfo.RecvACCM = 0;
			pCall->m_wanLinkInfo.RecvFramingBits = g_pAdapter->m_wanInfo.FramingBits;
			pCall->m_wanLinkInfo.SendACCM = 0;
			pCall->m_wanLinkInfo.SendFramingBits = g_pAdapter->m_wanInfo.FramingBits;
		}
		else if(ulState == LINECALLSTATE_DISCONNECTED)
			pCall->m_htCall = NULL;
		
		NdisReleaseSpinLock(&pCall->m_lockSelf);

		NdisMIndicateStatus(g_pAdapter->m_hMiniportAdapter,NDIS_STATUS_TAPI_INDICATION,&evTapi,sizeof(NDIS_TAPI_EVENT));
	}
	else
		NdisReleaseSpinLock(&pCall->m_lockSelf);
}

// Tspi init
NDIS_STATUS TspiInitialize(PADAPTER pAdapter,PNDIS_TAPI_PROVIDER_INITIALIZE pInit)
{
	NDIS_STATUS status = NDIS_STATUS_FAILURE;

	if(!pAdapter || !pInit)
		return NDIS_STATUS_TAPI_INVALPARAM;

	__try
	{
		// create line ptr array
		status = NdisAllocateMemoryWithTag((PVOID*)&pAdapter->m_pLinePtrArray,sizeof(PLINE_INFO)*pAdapter->m_ulNumLineDevs,'LNPT');

		NdisZeroMemory(pAdapter->m_pLinePtrArray,sizeof(PLINE_INFO) * pAdapter->m_ulNumLineDevs);

		// init handle table
		InitializeHandleTable(pAdapter->m_ulNumLineDevs * pAdapter->m_ulEndPoints);

		pAdapter->m_lProviderRefCount = 1;

		pAdapter->m_ulDeviceIdBase = pInit->ulDeviceIDBase;

		ReferenceAdapter(pAdapter,TRUE);

		pInit->ulNumLineDevs = pAdapter->m_ulNumLineDevs;

		pInit->ulProviderID = (ULONG_PTR)pAdapter->m_hMiniportAdapter;

		pAdapter->m_ulProviderFlags = PROVIDER_INITIALIZED;

		status = NDIS_STATUS_SUCCESS;
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		TspiCleanup(pAdapter);
	}

	return status;
}

// tspi clean up
VOID TspiCleanup(PADAPTER pAdapter)
{
	NdisAcquireSpinLock(&pAdapter->m_lockSelf);

	if(pAdapter->m_pLinePtrArray)
	{
		NdisFreeMemory(pAdapter->m_pLinePtrArray,sizeof(PLINE_INFO) * pAdapter->m_ulNumLineDevs,0);
	}

	if(pAdapter->m_pCallHandleTable)
		FreeHandleTable(pAdapter->m_pCallHandleTable);

	pAdapter->m_lProviderRefCount = 0;
	pAdapter->m_ulProviderFlags = PROVIDER_NOT_INITIALIZED;

	NdisReleaseSpinLock(&pAdapter->m_lockSelf);
}

// tspi open
NDIS_STATUS TspiOpen(PADAPTER pAdapter,PNDIS_TAPI_OPEN pOpen)
{
	NDIS_STATUS status = NDIS_STATUS_FAILURE;

	if(!pAdapter || !pOpen)
		return NDIS_STATUS_TAPI_INVALPARAM;

	__try
	{
		HDRV_LINE hDrvLine = GetHdLineFromDeviceId(pAdapter,pOpen->ulDeviceID);
		if(hDrvLine == -1)
			__leave;

		PLINE_INFO pLine = GetLinePtrFromHdLineCheckWorking(pAdapter,hDrvLine);
		if(pLine)
			__leave;

		status = NdisAllocateMemoryWithTag((PVOID*)&pLine,sizeof(LINE_INFO),'LINE');
		
		NdisZeroMemory(pLine,sizeof(LINE_INFO));

		pLine->m_ulSig = 'Line';
		pLine->m_lRefCount = 1;
		NdisAllocateSpinLock(&pLine->m_lockSelf);

		pLine->m_ulFlags = LINE_INITIALIZED;

		pLine->m_ulFlags |= LINE_CLIENT_MODE;

		pLine->m_htLine = pOpen->htLine;

		NdisInitializeListHead(&pLine->m_ltCall);

		pLine->m_ulEndpoints = pAdapter->m_ulEndPoints;

		pLine->m_hdLine = hDrvLine;

		NdisAcquireSpinLock(&pAdapter->m_lockSelf);
		
		pAdapter->m_pLinePtrArray[hDrvLine] = pLine;

		pAdapter->m_ulTotalLines ++;

		NdisReleaseSpinLock(&pAdapter->m_lockSelf);

		ReferenceTspiProvider(pAdapter,TRUE);

		pOpen->hdLine = hDrvLine;
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		
	}

	return status;
}

// Tspi make call
NDIS_STATUS TspiMakeCall(PADAPTER pAdapter,PNDIS_TAPI_MAKE_CALL pMakeCall)
{
	NDIS_STATUS status = NDIS_STATUS_FAILURE;

	if(!pAdapter || !pMakeCall)
		return NDIS_STATUS_TAPI_INVALPARAM;

	PPPPOE_WORK_ITEM pWorkItemMakeCall = NULL;
	PPPPOE_WORK_ITEM pWorkItemBind = NULL;
	PCALL_INFO pCall = NULL;
	HDRV_CALL hCallHandle = NULL;

	__try
	{
		PLINE_INFO pLine = GetLinePtrFromHdLineCheckWorking(pAdapter,pMakeCall->hdLine);
		if(!pLine)
		{
			status = NDIS_STATUS_TAPI_INVALLINEHANDLE;
			__leave;
		}

		// check mode
		if(!(pLine->m_ulFlags & LINE_CLIENT_MODE))
		{
			status = NDIS_STATUS_TAPI_ADDRESSBLOCKED;
			__leave;
		}

		// check quota
		if(pLine->m_ulNumOutCalls >= pLine->m_ulEndpoints / 2)
		{
			status = NDIS_STATUS_TAPI_OPERATIONUNAVAIL;
			__leave;
		}

		// XXX must not use default param
		if(pMakeCall->bUseDefaultLineCallParams)
		{
			status = NDIS_STATUS_TAPI_INVALCALLPARAMS;
			__leave;
		}

		// bearer mode must have data
		if(!(pMakeCall->LineCallParams.ulBearerMode & LINEBEARERMODE_DATA))
		{
			status = NDIS_STATUS_TAPI_INVALBEARERMODE;
			__leave;
		}

		// media mode
		if(!(pMakeCall->LineCallParams.ulMediaMode & LINEMEDIAMODE_DIGITALDATA))
		{
			status = NDIS_STATUS_TAPI_INVALMEDIAMODE;
			__leave;
		}

		// address mode
		if(!(pMakeCall->LineCallParams.ulAddressMode & (LINEADDRESSMODE_ADDRESSID | LINEADDRESSMODE_DIALABLEADDR)))
		{
			status = NDIS_STATUS_TAPI_INVALADDRESSMODE;
			__leave;
		}

		// address id must be 0
		if(pMakeCall->LineCallParams.ulAddressID > 0)
		{
			status = NDIS_STATUS_TAPI_INVALADDRESSID;
			__leave;
		}

		// allocate a call struct
		status = NdisAllocateMemoryWithTag((PVOID *)&pCall,sizeof(CALL_INFO),'CALL');

		InitializeCall(pCall,pLine,pMakeCall->htCall,FALSE);

		NdisAcquireSpinLock(&pAdapter->m_lockSelf);

		hCallHandle = InsertToHandleTable(pAdapter->m_pCallHandleTable,pCall,-1);

		NdisReleaseSpinLock(&pAdapter->m_lockSelf);

		if(!hCallHandle)
			ExRaiseStatus(status = NDIS_STATUS_TAPI_CALLUNAVAIL);

		// get ac name and serive name
		ULONG ulACNameStart = 0;
		ULONG ulACNameEnd = 0;
		ULONG ulServiceNameStart = 0;
		ULONG ulServiceNameEnd = 0;

		ULONG i = 0;
		ULONG ulTotalLen = pMakeCall->ulDestAddressSize;

		PUCHAR pDestAddr = reinterpret_cast<PUCHAR>(pMakeCall) + pMakeCall->ulDestAddressOffset;

		/*
		 *	format1 : " ac \ service "
		 *	format2 : " ac \ "
		 *	format3 : " service "
		 */
		while(i < ulTotalLen && pDestAddr[i])
		{
			// skip space
			while(i < ulTotalLen && pDestAddr[i] && pDestAddr[i] == ' ')
				i++;

			// check len
			if(i >= ulTotalLen || !pDestAddr[i])
				break;

			// ac name start
			ulACNameStart = ulACNameEnd = i;

			while(i < ulTotalLen)
			{
				if(pDestAddr[i] != ' ')
					ulACNameEnd = i;

				if(pDestAddr[i] == '\\' || !pDestAddr[i])
					break;

				i++;
			}

			// can't find a '\' total is service name
			if(i == ulTotalLen || !pDestAddr[i])
			{
				ulServiceNameStart = ulACNameStart;
				ulServiceNameEnd = ulACNameEnd;

				ulACNameEnd = ulACNameStart = 0;
				break;
			}

			++ i;


			// got here found a '\' get service name
			while(i < ulTotalLen && pDestAddr[i] && pDestAddr[i] == ' ')
				i++;

			ulServiceNameStart = ulServiceNameEnd = i;

			while(i < ulTotalLen)
			{
				if(pDestAddr[i] != ' ')
					ulServiceNameEnd = i;

				if(!pDestAddr[i])
					break;

				i++;
			}
		}

		// set ac name
		ULONG ulLen = ulACNameEnd - ulACNameStart;
		if(ulLen)
		{
			if(ulLen > 256)
				ulLen = 256;

			NdisMoveMemory( pCall->m_ucACName,pDestAddr + ulACNameStart,ulLen);

			pCall->m_usACNameLen = static_cast<USHORT>(ulLen);
			pCall->m_bMustCheckACName = TRUE;
		}

		// set service name
		ulLen = ulServiceNameEnd - ulServiceNameStart;
		if(ulLen)
		{
			if(ulLen > 256)
				ulLen = 256;

			NdisMoveMemory( pCall->m_ucServiceName,pDestAddr + ulServiceNameStart,ulLen);

			pCall->m_usServiceNameLen = static_cast<USHORT>(ulLen);
		}

		// allocate work item
		pWorkItemMakeCall = AllocateWorkItem(&g_lookasideWorkItem,ExecFsmMakeCall,NULL,NULL);
		if(!pWorkItemMakeCall)
			ExRaiseStatus(status = NDIS_STATUS_RESOURCES);

		pWorkItemMakeCall->m_param.FsmMakeFormat.m_pCall = pCall;

		pWorkItemBind = AllocateWorkItem(&g_lookasideWorkItem,ExecReEnumerateBindForMakeCall,NULL,NULL);
		if(!pWorkItemBind)
			ExRaiseStatus(status = NDIS_STATUS_RESOURCES);

		pWorkItemBind->m_param.MakeCallReEnumerateBindFormat.m_pCall = pCall;
		pWorkItemBind->m_param.MakeCallReEnumerateBindFormat.m_pFsmMakeCall = pWorkItemMakeCall;
		pWorkItemBind->m_param.MakeCallReEnumerateBindFormat.m_pMakeCall = pMakeCall;

		NdisAcquireSpinLock(&pLine->m_lockSelf);

		InsertHeadList(&pLine->m_ltCall,&pCall->m_ltCalls);

		pLine->m_ulNumOutCalls ++;

⌨️ 快捷键说明

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