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

📄 ndisprot.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	This routine is called by the NDIS driver when a general request
	completes. For synchronous requests, wake up the thread blocked.
	For asynchronous requests, call the completion handler.

Arguments:

    ProtocolBindingContext  Pointer to the binding structure

    NdisRequest             The posted request (this should actually
                            be a pointer to an NDIS_REQUEST_BETTER
                            structure)

    Status                  Completion status

Return Value:

    None

--*/
{
	PNDISWAN_ADAPTER	    pAdapter = (PNDISWAN_ADAPTER)ProtocolBindingContext;
    PNDIS_REQUEST_BETTER    pRequest = (PNDIS_REQUEST_BETTER)NdisRequest;

	DEBUGMSG(ZONE_MAC, (TEXT("PPP: PROTRequestComplete %hs pRequest=%x for adapter %s\n"),
		GetOidString(pRequest->Request.DATA.SET_INFORMATION.Oid), pRequest, pAdapter->szAdapterName));

	if (AdapterAddRef(pAdapter))
	{
		PppNdisRequestCompleteCb(pRequest, Status);
		AdapterDelRef(pAdapter);
	}
}

VOID
PppNdisIssueRequest(
				OUT	NDIS_STATUS				*pStatus,
				IN	PNDISWAN_ADAPTER        pAdapter,
				IN	DWORD					Type,	// NdisRequestSetInformation or NdisRequestQueryInformation
				IN	DWORD					Oid,
				IN	PVOID					InformationBuffer,
				IN	DWORD					InformationBufferLength,
	OPTIONAL	IN	macCntxt_t				*pMac,	// Reference session while request in progress if non-NULL
	OPTIONAL	IN	void					(*pCompletionFunc)(PNDIS_REQUEST_BETTER, PVOID FuncArg, NDIS_STATUS),
	OPTIONAL	IN	PVOID					FuncArg,
	OPTIONAL	OUT	PNDIS_REQUEST_BETTER	*ppRequest
	)
//
//	Send an NDIS Request to the miniport.
//
//	If pCompletionFunc is NULL
//	then on return ppRequest will be filled
//	in with the request allocated.  The caller is responsible for freeing
//	this structure (typically after blocking on the Event and extracting
//	the request's completion status).
//
{
	PNDIS_REQUEST_BETTER	pRequest;
	NDIS_STATUS				Status;
	pppSession_t			*s_p;

	DEBUGMSG(ZONE_FUNCTION, (TEXT("PPP: +PppNdisIssueRequest - Type=%x Oid=%hs (%x)\n"), Type, GetOidString(Oid), Oid));

	Status = NDIS_STATUS_RESOURCES;
	pRequest = pppAllocateMemory(sizeof(*pRequest));
	if (pRequest)
	{
		PNDIS_REQUEST	pNdisRequest = &pRequest->Request;

		DEBUGMSG(ZONE_ALLOC, (TEXT("PPP: PppNdisIssueRequest %x %hs pRequest=%x to adapter %s\n"),
			Type, GetOidString(Oid), pRequest, pAdapter->szAdapterName));
		pNdisRequest->RequestType = Type;
		if (Type == NdisRequestQueryInformation)
		{
			pNdisRequest->DATA.SET_INFORMATION.Oid = Oid;
			pNdisRequest->DATA.SET_INFORMATION.InformationBuffer = InformationBuffer;
			pNdisRequest->DATA.SET_INFORMATION.InformationBufferLength = InformationBufferLength;
		}
		else
		{
			pNdisRequest->DATA.QUERY_INFORMATION.Oid = Oid;
			pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer = InformationBuffer;
			pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength = InformationBufferLength;
		}

		//
		// Maintain a reference to the session while the request is
		// in progress for asynchronous (non-blocking) requests.
		// PppNdisRequestCompleteCb will dereference the session when
		// the request is completed.
		//

		s_p = NULL;
		if (pMac && pCompletionFunc)
		{
			s_p = PPPADDREFMAC(pMac, REF_ISSUEREQUEST);
			ASSERT(s_p);
		}

		pRequest->pSession = s_p;
		pRequest->pCompletionFunc = pCompletionFunc;
		pRequest->FuncArg = FuncArg;

		if (pCompletionFunc == NULL)
		{
			NdisInitializeEvent(&pRequest->Event);
			*ppRequest = pRequest;
		}

		NdisRequest (&Status, pAdapter->hAdapter, &pRequest->Request);

		//
		//	If the request completed synchronously, call the completion handler
		//
		if (Status != NDIS_STATUS_PENDING)
		{
			PppNdisRequestCompleteCb(pRequest, Status);
		}
	}
	else
	{
		DEBUGMSG(ZONE_ERROR, (TEXT("PPP: ERROR - Unable to allocate memory for NDIS request\n")));
	}
	DEBUGMSG(ZONE_FUNCTION, 
		(TEXT("PPP: -PppNdisIssueRequest - Type=%x Oid=%hs (%x)\n"), 
		Type, GetOidString(Oid), Oid));

	*pStatus = Status;
}

VOID
PppNdisDoSyncRequest(
				OUT NDIS_STATUS				*pStatus,
				IN	PNDISWAN_ADAPTER        pAdapter,
				IN	DWORD					Type,	// NdisRequestSetInformation or NdisRequestQueryInformation
				IN	DWORD					Oid,
				IN	PVOID					InformationBuffer,
				IN	DWORD					InformationBufferLength)
//
//	Issue a request to the adapter and do not return until the request is completed.
//
//	Note: Use with caution.  This function should not be called by any NDIS callback
//	thread, as doing so can result in deadlock.
//
{
	NDIS_REQUEST_BETTER	*pRequest;

	DEBUGMSG(ZONE_FUNCTION, 
		(TEXT("PPP: +PppNdisDoSyncRequest - Type=%x Oid=%hs (%x)\n"), 
		Type, GetOidString(Oid), Oid));

	//
	//	Note that a synchronous request has no need to take a reference
	//	to the session, since the calling thread will block and is
	//	presumed to already have a reference.
	//
	PppNdisIssueRequest(pStatus,
						pAdapter,
						Type,
						Oid,
						InformationBuffer,
						InformationBufferLength,
						NULL,
						NULL,
						NULL,
						&pRequest);

	NdisWaitEvent(&pRequest->Event, 0);
	*pStatus = pRequest->Status;

	PppNdisFreeRequest(pRequest);

	DEBUGMSG(ZONE_FUNCTION || ZONE_ERROR && (*pStatus != NDIS_STATUS_SUCCESS), 
		(TEXT("PPP: -PppNdisDoSyncRequest - Type=%x Oid=%hs (%x)\n"), 
		Type, GetOidString(Oid), Oid, *pStatus));
}

//** PROTWanRcv - PROT receive data handler.
//
//  This routine is called when data arrives from the NDIS driver.
//
//  Entry:
//      Handle - The binding handle we specified (really a pointer to an AI).
//      Context - NDIS context to be used for TD.
//      Header - Pointer to header
//      HeaderSize - Size of header
//      Data - Pointer to buffer of received data
//      Size - Byte count of data in buffer.
//      TotalSize - Byte count of total packet size.
//
//  Exit: Status indicating whether or not we took the packet.
//
NDIS_STATUS NDIS_API
PROTWanRcv(
	NDIS_HANDLE Handle,
	PUCHAR      Packet,
	ULONG       PacketSize)
{
	pppMsg_t		 pppMsg;
	macCntxt_t		*pMac = (macCntxt_t *)Handle;
	pppSession_t	*pSession;	
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("PPP: +PROTRcv(0x%X, 0x%X, %d)\r\n"), Handle, Packet, PacketSize));

#ifdef DEBUG
	DEBUGMSG( ZONE_PPP, (TEXT( "PPP: RX Packet: len %d data: %x\n" ), PacketSize, Packet ));
	if (ZONE_TRACE)
		DumpMem (Packet, PacketSize);
#endif

	//
	// Invoke packet debug extension if it is loaded.
	//
	if (g_pfnLogRxContigPacket)
	{
		BOOL bDoReceive;

		bDoReceive = g_pfnLogRxContigPacket(L"PPP", ((pppSession_t *)pMac->session)->context->AdapterName, L"PPP", Packet, PacketSize);
		if (!bDoReceive)
			return NDIS_STATUS_SUCCESS;
	}

	if (pSession = PPPADDREFMAC( pMac, REF_WANRCV ))
	{
		pppMsg.len  = PacketSize;
		pppMsg.data = Packet;
		pppMsg.cbMACPacket = 0; // RxPacketHandler will fill in size after framing/protocol bytes

		pppLock( pSession );
		pSession->RxPacketHandler( pSession, &pppMsg);
		pppUnLock( pSession );

		PPPDELREF( pSession, REF_WANRCV );
	}

	// Interface is marked as down.
	return NDIS_STATUS_SUCCESS;
}

//** PROTWanRcvComplete - PROT receive complete handler.
//
//  This routine is called by the NDIS driver after some number of
//  receives. In some sense, it indicates 'idle time'.
//
//  Entry:
//      Handle - The binding handle we specified (really a pointer to an AI).
//
//  Exit: Nothing.
//
void NDIS_API
PROTWanRcvComplete(NDIS_HANDLE Handle)
{
	macCntxt_t		*pMac = (macCntxt_t *)Handle;
	pppSession_t	*pSession;	

	DEBUGMSG (ZONE_FUNCTION, (TEXT("+PROTRcvComplete(0x%X)\r\n"), Handle));	

	if (pSession = PPPADDREFMAC( pMac, REF_WANRCVCOMPLETE))
	{
		// ReceiveComplete just indicates the completion to IP, don't bother
		// locking the session since it would just have to be unlocked prior
		// to calling into IPRcvComplete.
		ReceiveComplete(pSession);

		PPPDELREF( pSession, REF_WANRCVCOMPLETE );
	}

	DEBUGMSG (ZONE_FUNCTION, (TEXT("-PROTRcvComplete:\r\n")));
}

void
pppLine_GetSLIPLinkInfoCompleteCallback(
	IN	pppSession_t			*s_p,
	IN	NDIS_WAN_GET_LINK_INFO *pInfo,
	IN	NDIS_STATUS				Status
	)
{
	NDIS_WAN_SET_LINK_INFO *pSetInfo = (NDIS_WAN_SET_LINK_INFO *)pInfo;

	if (Status != NDIS_STATUS_SUCCESS)
	{
		DEBUGMSG( ZONE_ERROR, (TEXT( "PPP: Unable to change miniport to SLIP framing\n" )));
		pppChangeOfState( s_p, RASCS_Disconnected, 0 );
	}
	else
	{
		pSetInfo->SendFramingBits &= ~(PPP_FRAMING | PPP_MULTILINK_FRAMING);
		pSetInfo->SendFramingBits |= SLIP_FRAMING;
		pSetInfo->RecvFramingBits &= ~(PPP_FRAMING | PPP_MULTILINK_FRAMING);
		pSetInfo->RecvFramingBits |= SLIP_FRAMING;

		pppMac_SetLink( s_p->macCntxt, pSetInfo );

		// SLIP is now up, let IP and RAS know.

		LinkUpIndication( s_p->context );
		pppChangeOfState( s_p, RASCS_Connected, 0 );
	}

}

void
PppHandleLineConnectedEvent(
	pppSession_t *s_p)
//
//	This function is called after the line is connected to the peer.
//	That is, the basic ability to send/receive bytes is present and
//	we can proceed on to PPP protocol negotiations.
//
{
	switch( s_p->Mode )
	{
	case PPPMODE_PPP:

		DEBUGMSG( ZONE_PPP, (TEXT( "PPP:MacOpen,LCP Up\r\n" )));

		//
		// IP address assignment done during IPCP negotiation
		//

		pppLcp_LowerLayerUp(s_p->lcpCntxt);
		break;

	case PPPMODE_SLIP:
	case PPPMODE_CSLIP:

		DEBUGMSG( ZONE_PPP, (TEXT( "PPP:SLIP:MacOpen\r\n" )));

		//
		// Change the MAC framing mode to SLIP (default is PPP)
		//
		pppMac_GetLinkInfo(s_p->macCntxt, pppLine_GetSLIPLinkInfoCompleteCallback, s_p);

		break;

	default:
		ASSERT( 0 );
		break;
	}
}

void
PppHandleLineDisconnectedEvent(
	IN OUT pppSession_t  *s_p,
	IN OUT macCntxt_t	 *pMac)
//
//	This function is called after the line is disconnected from the peer.
//	That is, the basic ability to send/receive bytes has been lost.
//
{
	DWORD ErrorCode;

	switch( s_p->Mode )
	{
	case PPPMODE_PPP:
		DEBUGMSG( ZONE_PPP, (TEXT( "PPP:MacClosed\r\n" )));
		// Tell LCP that the MAC layer is down, LCP will tear down higher layers
		pppLcp_LowerLayerDown(s_p->lcpCntxt);
		break;

	case PPPMODE_SLIP:
	case PPPMODE_CSLIP:
		DEBUGMSG( ZONE_PPP, (TEXT( "PPP:SLIP:MacClosed\r\n" )));
		// Tear down the IP interface directly, since there is no IPCP when running SLIP
		LinkDownIndication( s_p->context, s_p);
		break;

	default:
		ASSERT( FALSE );
		break;
	}

	// Complete any pending call drop requests
	pppExecuteCompleteCallbacks(&pMac->pPendingCallDropCompleteList);

	if (s_p->HangUpReq)
		ErrorCode = NO_ERROR;
	else if (s_p->bDisconnectDueToUnresponsivePeer)
		ErrorCode = ERROR_IDLE_DISCONNECTED;
	else if (s_p->bUseRasErrorFromAuthFailure)
		ErrorCode = s_p->RasError;
	else
		ErrorCode = pMac->TapiEcode;

	// Indicate the Disconnected state
	pppChangeOfState( s_p, RASCS_Disconnected, ErrorCode);

	SetEvent(pMac->hNdisTapiEvent);
}

//** PROTStatus - PROT status handler.
//
//  Called by the NDIS driver when some sort of status change occurs.
//  We take action depending on the type of status.
//
//  Entry:
//      Handle - The binding handle we specified (really a pointer to an AI).
//      GStatus - General type of status that caused the call.
//      Status - Pointer to a buffer of status specific information.
//      StatusSize - Size of the status buffer.
//
//  Exit: Nothing.
//
void NDIS_API
PROTStatus(
	NDIS_HANDLE		Handle, 
	NDIS_STATUS		GStatus, 
	void			*Status,	
	uint			StatusSize)
{
	PNDISWAN_ADAPTER    pAdapter = (PNDISWAN_ADAPTER)Handle;
	PNDIS_TAPI_EVENT	pTapiEvent;
	macCntxt_t			*pMac;
	PNDIS_MAC_LINE_UP	pMacLineUp;
	PNDIS_MAC_LINE_DOWN	pMacLineDown;
	pppSession_t		*s_p;
	
	DEBUGMSG (ZONE_FUNCTION, (TEXT("PPP: +PROTStatus(0x%X, 0x%X, 0x%X, %d)\r\n"),
							   Handle, GStatus, Status, StatusSize));
	switch (GStatus)
	{
	case NDIS_STATUS_TAPI_INDICATION:
		pTapiEvent = (PNDIS_TAPI_EVENT)Status;
		ASSERT (StatusSize >= sizeof(NDIS_TAPI_EVENT));

		DEBUGMSG (ZONE_MAC, (TEXT("PPP: NDIS_STATUS_TAPI_INDICATION %d from MAC\n"), pTapiEvent->ulMsg));
		
		switch (pTapiEvent->ulMsg)
		{
		case LINE_CALLINFO :
			// Information about the call has changed.
			break;

⌨️ 快捷键说明

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