📄 tspi.cpp
字号:
NdisMoveMemory(pGetId + 1,pBuffer,ulLen);
}
return status;
}
// tspi shut down
NDIS_STATUS TspiShutdown(PADAPTER pAdapter,PNDIS_TAPI_PROVIDER_SHUTDOWN pShutdown,BOOLEAN bNeedComplete)
{
if(!pShutdown || !pAdapter)
return NDIS_STATUS_TAPI_INVALPARAM;
NdisAcquireSpinLock(&pAdapter->m_lockSelf);
if(!(pAdapter->m_ulProviderFlags & PROVIDER_INITIALIZED))
{
NdisReleaseSpinLock(&pAdapter->m_lockSelf);
return NDIS_STATUS_SUCCESS;
}
if(pAdapter->m_lProviderRefCount == 1)
{
pAdapter->m_ulProviderFlags &= ~PROVIDER_INITIALIZED;
pAdapter->m_ulProviderFlags |= PROVIDER_FREEING;
NdisReleaseSpinLock(&pAdapter->m_lockSelf);
DereferenceTspiProvider(pAdapter);
return NDIS_STATUS_SUCCESS;
}
pAdapter->m_ulProviderFlags |= PROVIDER_SHUTDOWNING;
if(bNeedComplete)
pAdapter->m_ulProviderFlags |= PROVIDER_SHUTDOWN_RETURN_PENDING;
ULONG ulLineIndex = 0;
for(;ulLineIndex < pAdapter->m_ulNumLineDevs;ulLineIndex ++)
{
PLINE_INFO pLine = pAdapter->m_pLinePtrArray[ulLineIndex];
if(pLine)
{
NdisReleaseSpinLock(&pAdapter->m_lockSelf);
NDIS_TAPI_CLOSE close;
close.hdLine = pLine->m_hdLine;
TspiClose(pAdapter,&close,FALSE);
NdisAcquireSpinLock(&pAdapter->m_lockSelf);
}
}
NdisReleaseSpinLock(&pAdapter->m_lockSelf);
DereferenceTspiProvider(pAdapter);
return NDIS_STATUS_PENDING;
}
// tspi answer
NDIS_STATUS TspiAnswer(PADAPTER pAdapter,PNDIS_TAPI_ANSWER pAnswer)
{
if(!pAnswer || !pAdapter)
return NDIS_STATUS_TAPI_INVALPARAM;
PCALL_INFO pCall = GetCallPtrFromCallHandle(pAdapter->m_pCallHandleTable,pAnswer->hdCall);
if(!pCall)
return NDIS_STATUS_TAPI_INVALCALLHANDLE;
return FsmAnswerCall(pCall);
}
// tspi close
NDIS_STATUS TspiClose(PADAPTER pAdapter,PNDIS_TAPI_CLOSE pClose,BOOLEAN bNeedComplete)
{
if(!pClose || !pAdapter)
return NDIS_STATUS_TAPI_INVALPARAM;
PLINE_INFO pLine = GetLinePtrFromHdLineCheckInitOnly(pAdapter,pClose->hdLine);
if(!pLine)
return NDIS_STATUS_TAPI_INVALLINEHANDLE;
NdisAcquireSpinLock(&pAdapter->m_lockSelf);
pAdapter->m_pLinePtrArray[pClose->hdLine] = NULL;
NdisReleaseSpinLock(&pAdapter->m_lockSelf);
NdisAcquireSpinLock(&pLine->m_lockSelf);
pLine->m_ulFlags &= ~LINE_SERVER_MODE;
pLine->m_ulFlags |= LINE_CLOSING;
if(bNeedComplete)
pLine->m_ulFlags |= LINE_CLOSE_RETURN_PENDING;
PLIST_ENTRY pEntry = pLine->m_ltCall.Flink;
while(pEntry != &pLine->m_ltCall)
{
PCALL_INFO pCall = CONTAINING_RECORD(pEntry,CALL_INFO,m_ltCalls);
NDIS_TAPI_CLOSE_CALL closeCall;
closeCall.hdCall = pCall->m_hdCall;
NdisReleaseSpinLock(&pLine->m_lockSelf);
TspiCloseCall(pAdapter,&closeCall,FALSE);
NdisAcquireSpinLock(&pLine->m_lockSelf);
pEntry = pLine->m_ltCall.Flink;
}
NdisReleaseSpinLock(&pLine->m_lockSelf);
if(!(pLine->m_ulFlags & LINE_CLOSE_RETURN_PENDING))
{
NDIS_TAPI_EVENT lineClose;
lineClose.htLine = pLine->m_htLine;
lineClose.ulMsg = LINE_CLOSE;
NdisMIndicateStatus(pAdapter->m_hMiniportAdapter,NDIS_STATUS_TAPI_INDICATION,&lineClose,sizeof(lineClose));
}
if(pAdapter->m_ulTotalLines == 1)
{
PPPPOE_WORK_ITEM pItem = AllocateWorkItem(&g_lookasideWorkItem,ExecTspiClose,NULL,NULL);
if(pItem)
{
ReferenceLine(pLine,TRUE);
pItem->m_param.TspiCloseFormat.m_pLine = pLine;
// ReferenceTspiProvider(pAdapter,TRUE);
ScheduleWorkItem(pItem);
}
}
DereferenceLine(pLine);
return NDIS_STATUS_PENDING;
}
// close work item
VOID ExecTspiClose(PPPPOE_WORK_ITEM pItem,PPPPOE_WORK_ITEM_PARAM pParam,PVOID pAdditionalParam)
{
ChangeLowerMiniportPacketFilter(FALSE);
DereferenceLine(pParam->TspiCloseFormat.m_pLine);
}
// tspi close call
NDIS_STATUS TspiCloseCall(PADAPTER pAdapter,PNDIS_TAPI_CLOSE_CALL pCloseCall,BOOLEAN bNeedComplete)
{
if(!pCloseCall || !pAdapter)
return NDIS_STATUS_TAPI_INVALPARAM;
PCALL_INFO pCall = GetCallPtrFromCallHandle(pAdapter->m_pCallHandleTable,pCloseCall->hdCall);
if(!pCall)
return NDIS_STATUS_TAPI_INVALCALLHANDLE;
NdisAcquireSpinLock(&pCall->m_lockSelf);
if(pCall->m_ulFlags & (CALL_FREEING | CALL_CLOSING))
{
NdisReleaseSpinLock(&pCall->m_lockSelf);
return NDIS_STATUS_FAILURE;
}
pCall->m_ulFlags |= CALL_CLOSING;
if(bNeedComplete)
pCall->m_ulFlags |= CALL_CLOSE_RETURN_PENDING;
NdisReleaseSpinLock(&pCall->m_lockSelf);
NDIS_TAPI_DROP drop;
drop.hdCall = pCall->m_hdCall;
TspiDrop(pAdapter,&drop,FALSE);
NdisAcquireSpinLock(&pCall->m_pLine->m_lockSelf);
RemoveEntryList(&pCall->m_ltCalls);
if(pCall->m_bRunAsServer)
pCall->m_pLine->m_ulNumInCalls --;
else
pCall->m_pLine->m_ulNumOutCalls --;
NdisReleaseSpinLock(&pCall->m_pLine->m_lockSelf);
NdisAcquireSpinLock(&pAdapter->m_lockSelf);
RemoveFromHandleTable(pAdapter->m_pCallHandleTable,pCall->m_hdCall);
NdisReleaseSpinLock(&pAdapter->m_lockSelf);
DereferenceCall(pCall);
return NDIS_STATUS_PENDING;
}
// tspi drop
NDIS_STATUS TspiDrop(PADAPTER pAdapter,PNDIS_TAPI_DROP pDrop,ULONG ulParam)
{
if(!pDrop || !pAdapter)
return NDIS_STATUS_TAPI_INVALPARAM;
PCALL_INFO pCall = GetCallPtrFromCallHandle(pAdapter->m_pCallHandleTable,pDrop->hdCall);
if(!pCall)
return NDIS_STATUS_TAPI_INVALCALLHANDLE;
PPPPOE_PACKET pPADTPacket = NULL;
__try
{
NdisAcquireSpinLock(&pCall->m_lockSelf);
if(pCall->m_ulFlags &(CALL_FREEING | CALL_DROPPING))
{
NdisReleaseSpinLock(&pCall->m_lockSelf);
__leave;
}
pCall->m_ulFlags &= ~(CALL_INITIALIZED|CALL_CONNECTING);
pCall->m_ulFlags |= CALL_DROPPING;
if(pCall->m_usSessionId && pCall->m_pBindContext)
{
pPADTPacket = InitializePADTToSend(pCall->m_macPeer,pCall->m_macSelf,pCall->m_usSessionId);
if(pPADTPacket)
{
ReferencePacket(pPADTPacket);
ReferenceBind(pCall->m_pBindContext,TRUE);
}
}
NdisReleaseSpinLock(&pCall->m_lockSelf);
CancelTimerItem(&g_timer,&pCall->m_timerPPPOEItem,(PVOID)1);
if(pPADTPacket)
{
SendPPPOEPacket(pAdapter,pCall->m_pBindContext,pPADTPacket);
DereferencePacket(pPADTPacket);
}
if(pCall->m_pBindContext)
RemoveCallFromBind(pCall,pCall->m_pBindContext);
if(pCall->m_htCall)
TspiCallStateChange(pCall,LINECALLSTATE_DISCONNECTED,ulParam);
DereferenceCall(pCall);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
return NDIS_STATUS_SUCCESS;
}
// tspi set default media detection
NDIS_STATUS TspiSetDefaultMediaDetection(PADAPTER pAdapter,PNDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION pDetection)
{
if(!pDetection || !pAdapter)
return NDIS_STATUS_TAPI_INVALPARAM;
PLINE_INFO pLine = GetLinePtrFromHdLineCheckWorking(pAdapter,pDetection->hdLine);
if(!pLine)
return NDIS_STATUS_TAPI_INVALLINEHANDLE;
if(pDetection->ulMediaModes & LINEMEDIAMODE_DIGITALDATA)
pLine->m_ulFlags |= LINE_SERVER_MODE;
else
pLine->m_ulFlags &= ~LINE_SERVER_MODE;
PPPPOE_WORK_ITEM pItem = AllocateWorkItem(&g_lookasideWorkItem,ExecSetDefMediaDetection,NULL,NULL);
if(!pItem)
return NDIS_STATUS_SUCCESS;
pItem->m_param.SetMediaDefaultDetectionFormat.m_pLine = pLine;
pItem->m_param.SetMediaDefaultDetectionFormat.m_pDetection = pDetection;
ScheduleWorkItem(pItem);
return NDIS_STATUS_PENDING;
}
// work item
VOID ExecSetDefMediaDetection(PPPPOE_WORK_ITEM pItem,PPPPOE_WORK_ITEM_PARAM pParam,PVOID pAdditionalParam)
{
NdisAcquireSpinLock(&g_lockBind);
g_bIsTimeToBind = TRUE;
NdisReleaseSpinLock(&g_lockBind);
NdisReEnumerateProtocolBindings(g_hProtocolHandle);
ChangeLowerMiniportPacketFilter(TRUE);
NdisMQueryInformationComplete(g_pAdapter->m_hMiniportAdapter,NDIS_STATUS_SUCCESS);
}
// tspi set status message
NDIS_STATUS TspiSetStatusMessage(PADAPTER pAdapter,PNDIS_TAPI_SET_STATUS_MESSAGES pStatusMessage)
{
if(!pStatusMessage || !pAdapter)
return NDIS_STATUS_TAPI_INVALPARAM;
return NDIS_STATUS_SUCCESS;
}
// indicate new call
VOID TspiIndicateNewCall(PCALL_INFO pCall)
{
NdisAcquireSpinLock(&pCall->m_lockSelf);
__try
{
if(pCall->m_ulFlags & (CALL_CLOSING | CALL_DROPPING))
__leave;
NdisReleaseSpinLock(&pCall->m_lockSelf);
NDIS_TAPI_EVENT newCall;
newCall.htLine = pCall->m_pLine->m_htLine;
newCall.htCall = 0;
newCall.ulMsg = LINE_NEWCALL;
newCall.ulParam1 = pCall->m_hdCall;
newCall.ulParam2 = 0;
newCall.ulParam3 = 0;
NdisMIndicateStatus(g_pAdapter->m_hMiniportAdapter,NDIS_STATUS_TAPI_INDICATION,&newCall,sizeof(newCall));
NdisAcquireSpinLock(&pCall->m_lockSelf);
pCall->m_htCall = newCall.ulParam2;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
NdisReleaseSpinLock(&pCall->m_lockSelf);
}
// receive call
VOID TspiReceiveCall(PADAPTER pAdapter,PBIND_CONTEXT pBind,PPPPOE_PACKET pPacket)
{
NdisAcquireSpinLock(&pAdapter->m_lockSelf);
ULONG ulSize = pAdapter->m_ulNumLineDevs * pAdapter->m_ulEndPoints;
USHORT usCallIndex = static_cast<USHORT>(ulSize / 2);
while(usCallIndex < ulSize)
{
PCALL_INFO pCall = GetCallPtrFromHandleTableIndex(pAdapter->m_pCallHandleTable,usCallIndex);
if(!pCall)
break;
}
if(usCallIndex != ulSize)
{
ULONG ulLineIndex = 0;
PLINE_INFO pLine = NULL;
while(ulLineIndex < pAdapter->m_ulNumLineDevs)
{
pLine = pAdapter->m_pLinePtrArray[ulLineIndex];
if(pLine && pLine->m_ulNumInCalls < pAdapter->m_ulEndPoints && (pLine->m_ulFlags & LINE_SERVER_MODE))
break;
ulLineIndex++;
pLine = NULL;
}
if(pLine)
{
PCALL_INFO pCall;
NDIS_STATUS status = NdisAllocateMemoryWithTag((PVOID*)&pCall,sizeof(CALL_INFO),'CALL');
if(status == NDIS_STATUS_SUCCESS)
{
InitializeCall(pCall,pLine,NULL,TRUE);
HDRV_CALL hdCall = InsertToHandleTable(pAdapter->m_pCallHandleTable,pCall,usCallIndex);
if(hdCall)
{
pCall->m_hdCall = hdCall;
NdisAcquireSpinLock(&pLine->m_lockSelf);
InsertHeadList(&pLine->m_ltCall,&pCall->m_ltCalls);
pLine->m_ulNumInCalls ++;
NdisReleaseSpinLock(&pLine->m_lockSelf);
NdisAcquireSpinLock(&pCall->m_lockSelf);
// one for the time
// one for drop
// one for close
pCall->m_lRefCount = 3;
NdisReleaseSpinLock(&pCall->m_lockSelf);
NdisReleaseSpinLock(&pAdapter->m_lockSelf);
FsmReceiveCall(pCall,pBind,pPacket);
DereferenceCall(pCall);
return;
}
else
{
CallCleanup(pCall);
}
}
}
}
NdisReleaseSpinLock(&pAdapter->m_lockSelf);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -