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

📄 tspi.cpp

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

		pLine->m_lRefCount ++;

		NdisReleaseSpinLock(&pLine->m_lockSelf);

		NdisAcquireSpinLock(&pCall->m_lockSelf);

		// one for drop
		// one for close
		// one for ExecFsmMakeCall
		pCall->m_lRefCount = 3;

		pMakeCall->hdCall = pCall->m_hdCall = hCallHandle;

		NdisReleaseSpinLock(&pCall->m_lockSelf);

		ScheduleWorkItem(pWorkItemBind);

		status = NDIS_STATUS_PENDING;
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		if(pWorkItemBind)
			NdisFreeToNPagedLookasideList(pWorkItemBind->m_pLookasideList,pWorkItemBind);

		if(pWorkItemMakeCall)
			NdisFreeToNPagedLookasideList(pWorkItemMakeCall->m_pLookasideList,pWorkItemMakeCall);

		if(hCallHandle)
		{
			NdisAcquireSpinLock(&pAdapter->m_lockSelf);

			RemoveFromHandleTable(pAdapter->m_pCallHandleTable,hCallHandle);

			NdisReleaseSpinLock(&pAdapter->m_lockSelf);
		}

		if(pCall)
			CallCleanup(pCall);
	}

	return status;
}

// tspi get extension id
NDIS_STATUS TspiGetExtensionId(PADAPTER pAdapter,PNDIS_TAPI_GET_EXTENSION_ID pExtensionId)
{
	if(!pExtensionId || !pAdapter)
		return NDIS_STATUS_TAPI_INVALPARAM;

	HDRV_LINE hdLine = GetHdLineFromDeviceId(pAdapter,pExtensionId->ulDeviceID);
	if(hdLine != -1)
	{
		pExtensionId->LineExtensionID.ulExtensionID0 = 0;
		pExtensionId->LineExtensionID.ulExtensionID1 = 0;
		pExtensionId->LineExtensionID.ulExtensionID2 = 0;
		pExtensionId->LineExtensionID.ulExtensionID3 = 0;

		return NDIS_STATUS_SUCCESS;
	}

	return NDIS_STATUS_TAPI_NODRIVER;
}

// get device caps
NDIS_STATUS TspiGetDeviceCaps(PADAPTER pAdapter,PNDIS_TAPI_GET_DEV_CAPS pDeviceCaps)
{
	UCHAR _s_ProviderInfo[] = "ISDN\0TCPPPOE";
	UCHAR _s_LineName[] = "TC PPPoE Line0000";
	
	if(!pDeviceCaps || !pAdapter)
		return NDIS_STATUS_TAPI_INVALPARAM;

	HDRV_LINE hdLine = GetHdLineFromDeviceId(pAdapter,pDeviceCaps->ulDeviceID);

	if(hdLine == -1)
		return NDIS_STATUS_TAPI_NODRIVER;

	pDeviceCaps->LineDevCaps.ulNeededSize = sizeof(LINE_DEV_CAPS) + sizeof(_s_ProviderInfo) + sizeof(_s_LineName);

	if(pDeviceCaps->LineDevCaps.ulTotalSize < pDeviceCaps->LineDevCaps.ulNeededSize)
		return NDIS_STATUS_INVALID_LENGTH;

	pDeviceCaps->LineDevCaps.ulUsedSize = pDeviceCaps->LineDevCaps.ulNeededSize;
	pDeviceCaps->LineDevCaps.ulBearerModes = LINEBEARERMODE_DATA;					// data mode
	pDeviceCaps->LineDevCaps.ulDevCapFlags = LINEDEVCAPFLAGS_CLOSEDROP;				// when line close,then drop all the calls
	pDeviceCaps->LineDevCaps.ulNumAddresses = 1;									// only one address
	pDeviceCaps->LineDevCaps.ulAddressModes = LINEADDRESSMODE_ADDRESSID | LINEADDRESSMODE_DIALABLEADDR;	// id or phone number
	pDeviceCaps->LineDevCaps.ulMaxRate = 100000000;									// 100 M
	pDeviceCaps->LineDevCaps.ulPermanentLineID = pDeviceCaps->ulDeviceID;			// device id
	pDeviceCaps->LineDevCaps.ulMaxNumActiveCalls = pAdapter->m_ulEndPoints;			// max calls
	pDeviceCaps->LineDevCaps.ulRingModes = 1;										// only one ring mode
	pDeviceCaps->LineDevCaps.ulStringFormat = STRINGFORMAT_ASCII;
	pDeviceCaps->LineDevCaps.ulProviderInfoSize = sizeof(_s_ProviderInfo);
	pDeviceCaps->LineDevCaps.ulProviderInfoOffset = sizeof(LINE_DEV_CAPS);
	pDeviceCaps->LineDevCaps.ulAnswerMode = LINEANSWERMODE_NONE;					// when answer no effect on this call
	pDeviceCaps->LineDevCaps.ulMediaModes = LINEMEDIAMODE_DIGITALDATA;				// digital data
	pDeviceCaps->LineDevCaps.ulLineNameOffset = sizeof(LINE_DEV_CAPS) + sizeof(_s_ProviderInfo);
	pDeviceCaps->LineDevCaps.ulLineNameSize = sizeof(_s_LineName);

	NdisMoveMemory(pDeviceCaps + 1,_s_ProviderInfo,sizeof(_s_ProviderInfo));

	ULONG ulOffset  = sizeof(_s_LineName) - 2;
	ULONG i = 0;
	while(i < 4)
	{
		UCHAR ucNum = (UCHAR)(hdLine % 10);
		hdLine /= 10;
		_s_LineName[ulOffset --] = ucNum + '0';
		i ++;
	}

	NdisMoveMemory(reinterpret_cast<PUCHAR>(pDeviceCaps + 1) + sizeof(_s_ProviderInfo),_s_LineName,sizeof(_s_LineName));

	return NDIS_STATUS_SUCCESS;
}

// tspi get call status
NDIS_STATUS TspiGetCallStatus(PADAPTER pAdapter,PNDIS_TAPI_GET_CALL_STATUS pCallStatus)
{
	if(!pCallStatus || !pAdapter)
		return NDIS_STATUS_TAPI_INVALPARAM;

	PCALL_INFO pCall = GetCallPtrFromCallHandle(pAdapter->m_pCallHandleTable,pCallStatus->hdCall);
	if(!pCall)
		return NDIS_STATUS_TAPI_INVALCALLHANDLE;

	pCallStatus->LineCallStatus.ulNeededSize = sizeof(LINE_CALL_STATUS);

	if(pCallStatus->LineCallStatus.ulTotalSize < pCallStatus->LineCallStatus.ulNeededSize)
		return NDIS_STATUS_INVALID_LENGTH;

	pCallStatus->LineCallStatus.ulUsedSize = pCallStatus->LineCallStatus.ulNeededSize;

	// XXXX
	pCallStatus->LineCallStatus.ulCallFeatures = LINECALLFEATURE_DROP | LINECALLFEATURE_DIAL;
	pCallStatus->LineCallStatus.ulCallPrivilege = LINECALLPRIVILEGE_OWNER;
	pCallStatus->LineCallStatus.ulCallState = pCall->m_ulCallState;

	switch(pCall->m_ulCallState)
	{
	case LINECALLSTATE_BUSY:
	case LINECALLSTATE_DIALTONE:
		pCallStatus->LineCallStatus.ulCallStateMode = LINEBUSYMODE_STATION;
		break;

	case LINECALLSTATE_DISCONNECTED:
		pCallStatus->LineCallStatus.ulCallStateMode = LINEDISCONNECTMODE_UNKNOWN;
		break;
	}

	return NDIS_STATUS_SUCCESS;
}

// tspi shut down
NDIS_STATUS TspiGetCallInfo(PADAPTER pAdapter,PNDIS_TAPI_GET_CALL_INFO pCallInfo)
{
	if(!pCallInfo || !pAdapter)
		return NDIS_STATUS_TAPI_INVALPARAM;

	PCALL_INFO pCall = GetCallPtrFromCallHandle(pAdapter->m_pCallHandleTable,pCallInfo->hdCall);
	if(!pCall)
		return NDIS_STATUS_TAPI_INVALCALLHANDLE;

	pCallInfo->LineCallInfo.ulNeededSize = sizeof(LINE_CALL_INFO) + 14;

	if(pCallInfo->LineCallInfo.ulTotalSize < pCallInfo->LineCallInfo.ulNeededSize)
		return NDIS_STATUS_INVALID_LENGTH;

	pCallInfo->LineCallInfo.ulUsedSize = pCallInfo->LineCallInfo.ulNeededSize;

	pCallInfo->LineCallInfo.ulLineDeviceID = pAdapter->m_ulDeviceIdBase + (ULONG)(pCall->m_pLine->m_hdLine);
	pCallInfo->LineCallInfo.ulAddressID = 0;									// only one address,so it must be 0
	pCallInfo->LineCallInfo.ulBearerMode = LINEBEARERMODE_DATA;					// data mode
	pCallInfo->LineCallInfo.ulRate = pCall->m_ulLinkSpeed;						// speed
	pCallInfo->LineCallInfo.ulCalledIDOffset = sizeof(LINE_CALL_INFO) + 7;		// called id offset,here id is mac address
	pCallInfo->LineCallInfo.ulCalledIDSize = 7;
	pCallInfo->LineCallInfo.ulCalledIDFlags = LINECALLPARTYID_ADDRESS;

	pCallInfo->LineCallInfo.ulCallerIDFlags = LINECALLPARTYID_ADDRESS;
	pCallInfo->LineCallInfo.ulCallerIDSize = 7;
	pCallInfo->LineCallInfo.ulCallerIDOffset = sizeof(LINE_CALL_INFO);
	pCallInfo->LineCallInfo.ulMediaMode = LINEMEDIAMODE_DIGITALDATA;			// digital data
	pCallInfo->LineCallInfo.ulCallParamFlags = LINECALLPARAMFLAGS_IDLE;			// idle

	pCallInfo->LineCallInfo.ulCallStates =  LINECALLSTATE_IDLE | LINECALLSTATE_OFFERING |
											LINECALLSTATE_DIALING | 
											LINECALLSTATE_PROCEEDING | LINECALLSTATE_CONNECTED |
											LINECALLSTATE_DISCONNECTED;			// supported call state

	PUCHAR pBuffer = reinterpret_cast<PUCHAR>(pCallInfo + 1);
	// set caller and called buffer
	if(pCall->m_bRunAsServer)
	{
		NdisMoveMemory(pBuffer,pCall->m_macPeer,6);
		NdisMoveMemory(pBuffer + 7,pCall->m_macSelf,6);
	}
	else
	{
		NdisMoveMemory(pBuffer,pCall->m_macSelf,6);
		NdisMoveMemory(pBuffer + 7,pCall->m_macPeer,6);
	}

	pBuffer[13] = 0;
	pBuffer[6] = 0;
	

	return NDIS_STATUS_SUCCESS;
}

// tspi address status
NDIS_STATUS TspiGetAddressStatus(PADAPTER pAdapter,PNDIS_TAPI_GET_ADDRESS_STATUS pStatus)
{
	if(!pStatus || !pAdapter)
		return NDIS_STATUS_TAPI_INVALPARAM;

	PLINE_INFO pLine = GetLinePtrFromHdLineCheckWorking(pAdapter,pStatus->hdLine);
	if(!pLine)
		return NDIS_STATUS_TAPI_INVALLINEHANDLE;

	if(pStatus->LineAddressStatus.ulTotalSize < pStatus->LineAddressStatus.ulNeededSize)
		return NDIS_STATUS_INVALID_LENGTH;

	pStatus->LineAddressStatus.ulNeededSize = sizeof(LINE_ADDRESS_STATUS);
	pStatus->LineAddressStatus.ulUsedSize = pStatus->LineAddressStatus.ulNeededSize;

	if(pStatus->ulAddressID)
		return NDIS_STATUS_TAPI_INVALADDRESSID;

	pStatus->LineAddressStatus.ulNumActiveCalls = pLine->m_ulNumOutCalls + pLine->m_ulNumInCalls;
	pStatus->LineAddressStatus.ulNumInUse = (pLine->m_ulNumOutCalls + pLine->m_ulNumInCalls) != 0;	// only one station allowed
	pStatus->LineAddressStatus.ulNumRingsNoAnswer = 999;									// 999 times ring
	pStatus->LineAddressStatus.ulAddressFeatures = pLine->m_ulNumOutCalls < pLine->m_ulEndpoints / 2 ? LINEADDRFEATURE_MAKECALL:0;
	pStatus->LineAddressStatus.ulAddressFeatures != pLine->m_ulNumInCalls < pLine->m_ulEndpoints / 2 ? LINEADDRFEATURE_PICKUP :0;

	return NDIS_STATUS_SUCCESS;
}

// tspi address caps
NDIS_STATUS TspiGetAddressCaps(PADAPTER pAdapter,PNDIS_TAPI_GET_ADDRESS_CAPS pCaps)
{
	static UCHAR _s_Address[] = "PPPoE VPN";

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

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

	HDRV_LINE hdLine = GetHdLineFromDeviceId(pAdapter,pCaps->ulDeviceID);
	if(hdLine == -1)
		return NDIS_STATUS_TAPI_INVALLINEHANDLE;

	if(pCaps->ulAddressID)
		return NDIS_STATUS_TAPI_INVALADDRESSID;

	if(pCaps->ulExtVersion != 0 && pCaps->ulExtVersion != NDIS_TAPI_CURRENT_VERSION)
		return NDIS_STATUS_TAPI_INCOMPATIBLEEXTVERSION;

	pCaps->LineAddressCaps.ulNeededSize = sizeof(LINE_ADDRESS_CAPS) + sizeof(_s_Address);

	if(pCaps->LineAddressCaps.ulTotalSize < pCaps->LineAddressCaps.ulNeededSize)
		return NDIS_STATUS_INVALID_LENGTH;

	pCaps->LineAddressCaps.ulUsedSize = pCaps->LineAddressCaps.ulNeededSize;

	pCaps->LineAddressCaps.ulDialToneModes = LINEDIALTONEMODE_NORMAL;
	pCaps->LineAddressCaps.ulSpecialInfo = LINESPECIALINFO_UNAVAIL;
	pCaps->LineAddressCaps.ulDisconnectModes = LINEDISCONNECTMODE_NORMAL | LINEDISCONNECTMODE_UNKNOWN | LINEDISCONNECTMODE_REJECT|
											   LINEDISCONNECTMODE_CONGESTION | LINEDISCONNECTMODE_INCOMPATIBLE |
											   LINEDISCONNECTMODE_NODIALTONE /*| LINEDISCONNECTMODE_OUTOFORDER*/;

	pCaps->LineAddressCaps.ulAddressStates = 0;										// no need address change
	pCaps->LineAddressCaps.ulMaxNumTransConf = 1;
	pCaps->LineAddressCaps.ulAddressSharing = LINEADDRESSSHARING_PRIVATE;			// private address
	pCaps->LineAddressCaps.ulMaxNumActiveCalls = pAdapter->m_ulEndPoints;
	pCaps->LineAddressCaps.ulAddrCapFlags = LINEADDRCAPFLAGS_DIALED;				// can dialed

	pCaps->LineAddressCaps.ulCallFeatures = LINECALLFEATURE_ACCEPT| LINECALLFEATURE_ANSWER |
											LINECALLFEATURE_COMPLETECALL | LINECALLFEATURE_DIAL | LINECALLFEATURE_DROP;

	pCaps->LineAddressCaps.ulCallStates =   LINECALLSTATE_IDLE | LINECALLSTATE_OFFERING |
											LINECALLSTATE_DIALING | 
											LINECALLSTATE_PROCEEDING | LINECALLSTATE_CONNECTED |
											LINECALLSTATE_DISCONNECTED;

	pCaps->LineAddressCaps.ulAddressSize = sizeof(_s_Address);
	pCaps->LineAddressCaps.ulAddressOffset = sizeof(LINE_ADDRESS_CAPS);
	NdisMoveMemory(pCaps + 1,_s_Address,sizeof(_s_Address));

	return NDIS_STATUS_SUCCESS;
}

// tspi ext version
NDIS_STATUS TspiNegotiateExtVersion(PADAPTER pAdapter,PNDIS_TAPI_NEGOTIATE_EXT_VERSION pVersion)
{
	if(!pVersion || !pAdapter)
		return NDIS_STATUS_TAPI_INVALPARAM;

	if(pVersion->ulLowVersion > NDIS_TAPI_CURRENT_VERSION || pVersion->ulHighVersion < NDIS_TAPI_CURRENT_VERSION)
		return NDIS_STATUS_TAPI_INCOMPATIBLEEXTVERSION;

	pVersion->ulExtVersion = NDIS_TAPI_CURRENT_VERSION;

	return NDIS_STATUS_SUCCESS;
}

// tspi get id
NDIS_STATUS TspiGetId(PADAPTER pAdapter,PNDIS_TAPI_GET_ID pGetId,ULONG ulLen)
{
	if(!pGetId || !pAdapter)
		return NDIS_STATUS_TAPI_INVALPARAM;

	if(pGetId->ulDeviceClassOffset + pGetId->ulDeviceClassSize < ulLen)
		return NDIS_STATUS_TAPI_INVALPARAM;

	NDIS_STATUS status = NDIS_STATUS_TAPI_INVALPARAM;

	ULONG_PTR ulDeviceId;
	PVOID pBuffer = NULL;
	__try
	{
		switch(pGetId->ulSelect)
		{
		case LINECALLSELECT_LINE:
			{
				status = NDIS_STATUS_TAPI_INVALDEVICECLASS;
				if(pGetId->ulDeviceClassSize != sizeof("tapi/line"))
					__leave;

				if(_strnicmp(reinterpret_cast<PCHAR>(pGetId)+pGetId->ulDeviceClassOffset,"tapi/line",pGetId->ulDeviceClassSize))
					__leave;

				status = NDIS_STATUS_INVALID_LENGTH;
				pGetId->DeviceID.ulNeededSize = sizeof(VAR_STRING) + sizeof(ULONG);
				if(pGetId->DeviceID.ulTotalSize < pGetId->DeviceID.ulNeededSize)
					__leave;

				pGetId->DeviceID.ulUsedSize = pGetId->DeviceID.ulNeededSize;

				status = NDIS_STATUS_TAPI_INVALLINEHANDLE;
				PLINE_INFO pLine = GetLinePtrFromHdLineCheckWorking(pAdapter,pGetId->hdLine);
				
				ulDeviceId = pLine->m_hdLine + pAdapter->m_ulDeviceIdBase;
				ulLen = sizeof(ULONG);
				pBuffer = &ulDeviceId;
				status = NDIS_STATUS_SUCCESS;
			}
			break;

		case LINECALLSELECT_CALL:
			{
				status = NDIS_STATUS_TAPI_INVALDEVICECLASS;
				if(pGetId->ulDeviceClassSize != sizeof("ndis"))
					__leave;

				if(_strnicmp(reinterpret_cast<PCHAR>(pGetId)+pGetId->ulDeviceClassOffset,"ndis",pGetId->ulDeviceClassSize))
					__leave;

				status = NDIS_STATUS_INVALID_LENGTH;
				pGetId->DeviceID.ulNeededSize = sizeof(VAR_STRING) + sizeof(ULONG);
				if(pGetId->DeviceID.ulTotalSize < pGetId->DeviceID.ulNeededSize)
					__leave;

				pGetId->DeviceID.ulUsedSize = pGetId->DeviceID.ulNeededSize;

				status = NDIS_STATUS_TAPI_INVALCALLHANDLE;
				PCALL_INFO pCall = GetCallPtrFromCallHandle(pAdapter->m_pCallHandleTable,pGetId->hdCall);

				NdisAcquireSpinLock(&pCall->m_lockSelf);

				if(pCall->m_ulCallState != LINECALLSTATE_CONNECTED)
				{
					NdisReleaseSpinLock(&pCall->m_lockSelf);
					status = NDIS_STATUS_TAPI_OPERATIONUNAVAIL;
					__leave;
				}

				NDIS_MAC_LINE_UP lineUp;
				
				lineUp.LinkSpeed = pCall->m_ulLinkSpeed;
				lineUp.Quality = NdisWanErrorControl;
				lineUp.SendWindow = 0;
				lineUp.NdisLinkContext = NULL;
				lineUp.ConnectionWrapperID = (NDIS_HANDLE)pCall->m_htCall;
				lineUp.NdisLinkHandle = (NDIS_HANDLE)pCall->m_hdCall;
				
				pCall->m_lRefCount ++;

				NdisReleaseSpinLock(&pCall->m_lockSelf);

				NdisMIndicateStatus(pAdapter->m_hMiniportAdapter,NDIS_STATUS_WAN_LINE_UP,&lineUp,sizeof(lineUp));

				NdisAcquireSpinLock(&pCall->m_lockSelf);

				pCall->m_hLinkContext = lineUp.NdisLinkContext;

				pCall->m_ulFsmState = FSM_SESSION;

				ScheduleIndicateRecvedPacketTimer(pCall);

				NdisReleaseSpinLock(&pCall->m_lockSelf);

				DereferenceCall(pCall);

				ulDeviceId = (ULONG_PTR)lineUp.NdisLinkContext;
				ulLen = sizeof(ULONG);
				pBuffer = &ulDeviceId;
				status = NDIS_STATUS_SUCCESS;
			}
			break;

		case LINECALLSELECT_ADDRESS:
			break;
		}
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
	}

	if(pBuffer)
	{
		pGetId->DeviceID.ulStringFormat = STRINGFORMAT_BINARY;
		pGetId->DeviceID.ulStringSize = ulLen;
		pGetId->DeviceID.ulStringOffset = sizeof(VAR_STRING);

⌨️ 快捷键说明

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