📄 ndisprot.c
字号:
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 + -