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