📄 misc.c
字号:
--*/
{
PNDIS_BUFFER pPktBuffer;
PVOID pPktBufferVA, pDstBufferVA;
UINT uiBufSize, uiTotalLen, uiMdlSizeLeft;
UINT uiCopySize, uiTotalBytesCopied;
NdisGetFirstBufferFromPacket(pPkt,
&pPktBuffer,
&pPktBufferVA,
&uiBufSize,
&uiTotalLen);
ASSERT(pPktBuffer && (0 != uiBufSize));
uiTotalBytesCopied = 0;
uiMdlSizeLeft = MmGetMdlByteCount(pIrp->MdlAddress);
pDstBufferVA = MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority);
if(pDstBufferVA != NULL && uiMdlSizeLeft != 0)
{
while(pPktBuffer)
{
uiCopySize = (uiMdlSizeLeft < uiBufSize) ? uiMdlSizeLeft :uiBufSize;
// copy the data
NdisMoveMemory(pDstBufferVA, pPktBufferVA, uiCopySize);
pDstBufferVA = (PVOID) ((PCHAR)pDstBufferVA + uiCopySize);
uiTotalBytesCopied += uiCopySize;
uiMdlSizeLeft -= uiCopySize;
if(uiMdlSizeLeft <= 0)
break;
// get the next buffer
NdisGetNextBuffer(pPktBuffer, &pPktBuffer);
// get details of the new buffer
if(pPktBuffer)
NdisQueryBuffer(pPktBuffer, &pPktBufferVA, &uiBufSize);
}
}
return uiTotalBytesCopied;
}
VOID AtmSmRecvReturnTimerFunction (
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3
)
/*++
Routine Description:
This timer function, checks to see there are any buffered packets that has
been around for a while. If so it gives the packet back to the miniport
driver.
It queues itself back if there are anymore packets in the queue
We use NdisGetSystemUpTime, since that is all the resolution we want
Arguments:
SystemSpecific1 - Not used
FunctionContext - Adapter
SystemSpecific2 - Not used
SystemSpecific3 - Not used
Return Value:
None.
--*/
{
PATMSM_ADAPTER pAdapt = (PATMSM_ADAPTER)FunctionContext;
ULONG ulTime;
BOOLEAN bShouldQueueTimerAgain = FALSE;
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
pAdapt->fRecvTimerQueued = FALSE;
NdisGetSystemUpTime(&ulTime);
// check if any packets have been sitting around for long
// if so, return them
while(pAdapt->pRecvPktNext)
{
PPROTO_RSVD pPRsvd;
PNDIS_PACKET pPkt;
pPkt = pAdapt->pRecvPktNext;
pPRsvd = GET_PROTO_RSVD(pPkt);
if((ulTime - pPRsvd->ulTime) >= RECV_BUFFERING_TIME)
{
pAdapt->pRecvPktNext = pPRsvd->pPktNext;
if(pAdapt->pRecvLastPkt == pPkt)
pAdapt->pRecvLastPkt = NULL;
DbgVeryLoud(("Returning a packet that was buffered too long\n"));
pAdapt->ulRecvPktsCount--;
// release the recv queue lock
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
// return the packet to the miniport
NdisReturnPackets(&pPkt, 1);
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
}
else
{
// time hasn't expired for this packet
ulTime = RECV_BUFFERING_TIME - (ulTime - pPRsvd->ulTime);
bShouldQueueTimerAgain = TRUE;
break;
}
}
if(bShouldQueueTimerAgain)
{
SET_ADAPTER_RECV_TIMER(pAdapt, ulTime);
}
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
return;
}
VOID AtmSmConnectToPMPDestinations(
IN PATMSM_VC pVc
)
/*++
Routine Description:
This will make a call to the destination in PMP case. It will MakeCall
to the first member. Subsequent destinations are added using AddParty.
Arguments:
pVc - Ptr to a PMP Vc
Return Value:
None
--*/
{
PATMSM_ADAPTER pAdapt = (PATMSM_ADAPTER)pVc->pAdapt;
BOOLEAN bLockReleased = FALSE;
PCO_CALL_PARAMETERS pCallParameters;
NDIS_HANDLE ProtocolVcContext;
NDIS_HANDLE ProtocolPartyContext;
NDIS_STATUS Status;
PATMSM_PMP_MEMBER pMember;
TraceIn(AtmSmConnectToPMPDestinations);
ASSERT(VC_TYPE_PMP_OUTGOING == pVc->VcType);
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
do
{ // break off loop
// First find any member addresses that is not yet connected
for(pMember = pVc->pPMPMembers; pMember; pMember = pMember->pNext)
if(ATMSM_GET_MEMBER_STATE(pMember) == ATMSM_MEMBER_IDLE)
break;
// if there are no - more members to be connected then get out
if(!pMember)
{
break;
}
ProtocolVcContext = (NDIS_HANDLE)pVc;
ProtocolPartyContext = (NDIS_HANDLE)pMember;
//
// First see if we have connected 1 or more members
//
if(0 == pVc->ulNumActiveMembers)
{
// No one is connected yet, so do a MakeCall
ASSERT(ATMSM_GET_VC_STATE(pVc) != ATMSM_VC_ACTIVE);
if(NULL == pVc->NdisVcHandle)
{
Status = NdisCoCreateVc(
pAdapt->NdisBindingHandle,
pAdapt->NdisAfHandle,
(NDIS_HANDLE)pVc,
&pVc->NdisVcHandle
);
if(NDIS_STATUS_SUCCESS != Status)
{
break;
}
DbgVeryLoud(("AddMembers: Created VC, VC %x, NdisVcHandle %x\n",
pVc, pVc->NdisVcHandle));
}
ASSERT(NULL != pVc->NdisVcHandle);
pCallParameters = AtmSmPrepareCallParameters(pAdapt,
&pMember->HwAddr,
TRUE,
TRUE);
if(pCallParameters == (PCO_CALL_PARAMETERS)NULL)
{
Status = NdisCoDeleteVc(pVc->NdisVcHandle);
ASSERT(NDIS_STATUS_SUCCESS == Status);
pVc->NdisVcHandle = NULL;
Status = NDIS_STATUS_RESOURCES;
break;
}
ATMSM_SET_VC_STATE(pVc, ATMSM_VC_SETUP_IN_PROGRESS);
ATMSM_SET_MEMBER_STATE(pMember, ATMSM_MEMBER_CONNECTING);
pVc->ulNumConnectingMembers++;
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
bLockReleased = TRUE;
Status = NdisClMakeCall(
pVc->NdisVcHandle,
pCallParameters,
ProtocolPartyContext,
&pMember->NdisPartyHandle
);
if(NDIS_STATUS_PENDING != Status)
{
AtmSmMakeCallComplete(
Status,
ProtocolVcContext,
pMember->NdisPartyHandle,
pCallParameters
);
}
}
else
{
// we have atleast one connected member, add the rest using AddParty
ASSERT(NULL != pVc->NdisVcHandle);
pCallParameters = AtmSmPrepareCallParameters(pAdapt,
&pMember->HwAddr,
FALSE,
TRUE);
if(pCallParameters == (PCO_CALL_PARAMETERS)NULL)
{
Status = NDIS_STATUS_RESOURCES;
break;
}
ATMSM_SET_VC_STATE(pVc, ATMSM_VC_ADDING_PARTIES);
ATMSM_SET_MEMBER_STATE(pMember, ATMSM_MEMBER_CONNECTING);
pVc->ulNumConnectingMembers++;
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
bLockReleased = TRUE;
Status = NdisClAddParty(
pVc->NdisVcHandle,
ProtocolPartyContext,
pCallParameters,
&pMember->NdisPartyHandle
);
if(NDIS_STATUS_PENDING != Status)
{
AtmSmAddPartyComplete(
Status,
ProtocolPartyContext,
pMember->NdisPartyHandle,
pCallParameters
);
}
}
}while(FALSE);
if(!bLockReleased)
{
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
}
if(pVc->ulNumActiveMembers &&
(pVc->ulNumActiveMembers == pVc->ulNumTotalMembers))
{
PIRP pIrp;
//
// 1 or more members are connected, send any packets pending on the VC.
//
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
DbgInfo(("PMP VC 0x%x connected - %u members\n", pVc,
pVc->ulNumActiveMembers));
ATMSM_SET_VC_STATE(pVc, ATMSM_VC_ACTIVE);
// now complete IRP that started this connect call
pIrp = pVc->pConnectIrp;
pVc->pConnectIrp = NULL;
ASSERT(pIrp);
// remove the Vc from the inactive list
RemoveEntryList(&pVc->List);
// insert the vc into the active list
InsertHeadList(&pAdapt->ActiveVcHead, &pVc->List);
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
if(pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
// now set the connect context
*(PHANDLE)(pIrp->AssociatedIrp.SystemBuffer) = (HANDLE)pVc;
pIrp->IoStatus.Information = sizeof(HANDLE);
IoCompleteRequest(pIrp, IO_NETWORK_INCREMENT);
}
AtmSmSendQueuedPacketsOnVc(pVc);
}
else
{
if(0 == pVc->ulNumTotalMembers)
{
// now complete IRP that started this connect call
PIRP pIrp = pVc->pConnectIrp;
pVc->pConnectIrp = NULL;
ASSERT(pIrp);
if(pIrp)
{
pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NETWORK_INCREMENT);
}
DbgInfo(("PMP VC 0x%x failed to connect any members\n", pVc));
// Cleanup the VC - remove the reference added at create
AtmSmDereferenceVc(pVc);
}
}
TraceOut(AtmSmConnectToPMPDestinations);
}
VOID AtmSmConnectPPVC(
IN PATMSM_VC pVc
)
/*++
Routine Description:
This will make a call to the destination in PP case. It will MakeCall
to the destination.
Arguments:
pVc - Ptr to a PP Vc
Return Value:
None
--*/
{
PATMSM_ADAPTER pAdapt = (PATMSM_ADAPTER)pVc->pAdapt;
BOOLEAN bLockReleased = FALSE;
PCO_CALL_PARAMETERS pCallParameters;
NDIS_HANDLE ProtocolVcContext;
NDIS_STATUS Status;
TraceIn(AtmSmConnectPPVC);
ASSERT(VC_TYPE_PP_OUTGOING == pVc->VcType);
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
do
{ // break off loop
ProtocolVcContext = (NDIS_HANDLE)pVc;
ASSERT(ATMSM_GET_VC_STATE(pVc) != ATMSM_VC_ACTIVE);
ASSERT(NULL == pVc->NdisVcHandle);
if(NULL == pVc->NdisVcHandle)
{
Status = NdisCoCreateVc(
pAdapt->NdisBindingHandle,
pAdapt->NdisAfHandle,
(NDIS_HANDLE)pVc,
&pVc->NdisVcHandle
);
if(NDIS_STATUS_SUCCESS != Status)
{
break;
}
DbgVeryLoud(("Connect: Created VC, VC %x, NdisVcHandle %x\n",
pVc, pVc->NdisVcHandle));
}
ASSERT(NULL != pVc->NdisVcHandle);
pCallParameters = AtmSmPrepareCallParameters(pAdapt,
&pVc->HwAddr,
TRUE,
FALSE);
if(pCallParameters == (PCO_CALL_PARAMETERS)NULL)
{
Status = NdisCoDeleteVc(pVc->NdisVcHandle);
pVc->NdisVcHandle = NULL;
Status = NDIS_STATUS_RESOURCES;
break;
}
ATMSM_SET_VC_STATE(pVc, ATMSM_VC_SETUP_IN_PROGRESS);
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
bLockReleased = TRUE;
Status = NdisClMakeCall(
pVc->NdisVcHandle,
pCallParameters,
NULL,
NULL
);
if(NDIS_STATUS_PENDING != Status)
{
AtmSmMakeCallComplete(
Status,
ProtocolVcContext,
NULL,
pCallParameters
);
}
}while(FALSE);
if(!bLockReleased)
{
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
}
TraceOut(AtmSmConnectPPVC);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -