📄 tspi.cpp
字号:
//********************************************************************
// 日期: 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 + -