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

📄 ndisprot.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//

//  Include Files

#include "windows.h"
#include "ndis.h"
#include "ras.h"
#include "raserror.h"
#include "cxport.h"
#include "protocol.h"
#include "ppp.h"
#include "lcp.h"
#include "macp.h"
#include "ndistapi.h"
#include "cclib.h"


typedef DWORD IPAddr;
typedef DWORD IPMask;
#include "ip_intf.h"

// ----------------------------------------------------------------
//
//	Global Data
//
// ----------------------------------------------------------------
#define PPP_NDIS_PROTOCOL_NAME	TEXT("PPP")
static WCHAR NDISPROTName[] = PPP_NDIS_PROTOCOL_NAME;


#ifndef NDIS_API
#define NDIS_API
#endif

// Some forward declarations
void NDIS_API PROTOAComplete(NDIS_HANDLE Handle, NDIS_STATUS Status,
							 NDIS_STATUS ErrorStatus);
void NDIS_API PROTCAComplete(NDIS_HANDLE Handle, NDIS_STATUS Status);
void NDIS_API PROTSendComplete(NDIS_HANDLE Handle, PNDIS_WAN_PACKET Packet,
							   NDIS_STATUS Status);
void NDIS_API PROTTDComplete(NDIS_HANDLE Handle, PNDIS_PACKET Packet,
							 NDIS_STATUS Status, uint BytesCopied);
void NDIS_API PROTResetComplete(NDIS_HANDLE Handle, NDIS_STATUS Status);
void NDIS_API PROTRequestComplete(NDIS_HANDLE Handle, PNDIS_REQUEST Request,
								  NDIS_STATUS Status);
NDIS_STATUS NDIS_API PROTWanRcv(NDIS_HANDLE Handle, PUCHAR Packet, ULONG PacketSize);
void NDIS_API PROTWanRcvComplete(NDIS_HANDLE Handle);
void NDIS_API PROTStatus(NDIS_HANDLE Handle, NDIS_STATUS GStatus, void *Status,
						 uint StatusSize);
void NDIS_API PROTStatusComplete(NDIS_HANDLE Handle);
void NDIS_API PROTBindAdapter(PNDIS_STATUS RetStatus, NDIS_HANDLE BindContext,
							 PNDIS_STRING AdapterName, PVOID SS1, PVOID SS2);

void NDIS_API PROTUnbindAdapter(PNDIS_STATUS RetStatus,
							   NDIS_HANDLE ProtBindContext,
							   NDIS_HANDLE UnbindContext);


NDIS_PROTOCOL_CHARACTERISTICS PROTCharacteristics = {
    4,	// MAJOR Version
    0,	// MINOR Version
    0,
    PROTOAComplete,
    PROTCAComplete,
    (SEND_COMPLETE_HANDLER)PROTSendComplete,
    PROTTDComplete,
    PROTResetComplete,
    PROTRequestComplete,
	(RECEIVE_HANDLER)PROTWanRcv,
    PROTWanRcvComplete,
    PROTStatus,
    PROTStatusComplete,
    {   
		sizeof(PPP_NDIS_PROTOCOL_NAME) - sizeof(WCHAR), // Length in bytes not including terminating NULL
        sizeof(PPP_NDIS_PROTOCOL_NAME) - sizeof(WCHAR), // MaximumLength in bytes
        PPP_NDIS_PROTOCOL_NAME                          // PWSTR Buffer
    },
	NULL,	// Receive Packet Handler
	PROTBindAdapter,	// BindAdapterHandler
    PROTUnbindAdapter,	// UnbindAdapterHandler
    NULL,	// TranslateHandler
    NULL	// UnloadHandler
};

#if DEBUG
PCHAR
GetOidString(
    NDIS_OID Oid
    )
{
    PCHAR OidName;

    #define OID_CASE(oid) case (oid): OidName = #oid; break
    switch (Oid)
    {
        OID_CASE(OID_GEN_CURRENT_LOOKAHEAD);
        OID_CASE(OID_GEN_DRIVER_VERSION);
        OID_CASE(OID_GEN_HARDWARE_STATUS);
        OID_CASE(OID_GEN_LINK_SPEED);
        OID_CASE(OID_GEN_MAC_OPTIONS);
        OID_CASE(OID_GEN_MAXIMUM_LOOKAHEAD);
        OID_CASE(OID_GEN_MAXIMUM_FRAME_SIZE);
        OID_CASE(OID_GEN_MAXIMUM_TOTAL_SIZE);
        OID_CASE(OID_GEN_MEDIA_SUPPORTED);
        OID_CASE(OID_GEN_MEDIA_IN_USE);
        OID_CASE(OID_GEN_RECEIVE_BLOCK_SIZE);
        OID_CASE(OID_GEN_RECEIVE_BUFFER_SPACE);
        OID_CASE(OID_GEN_SUPPORTED_LIST);
        OID_CASE(OID_GEN_TRANSMIT_BLOCK_SIZE);
        OID_CASE(OID_GEN_TRANSMIT_BUFFER_SPACE);
        OID_CASE(OID_GEN_VENDOR_DESCRIPTION);
        OID_CASE(OID_GEN_VENDOR_ID);
		OID_CASE(OID_802_3_CURRENT_ADDRESS);
        OID_CASE(OID_TAPI_ACCEPT);
        OID_CASE(OID_TAPI_ANSWER);
        OID_CASE(OID_TAPI_CLOSE);
        OID_CASE(OID_TAPI_CLOSE_CALL);
        OID_CASE(OID_TAPI_CONDITIONAL_MEDIA_DETECTION);
        OID_CASE(OID_TAPI_CONFIG_DIALOG);
        OID_CASE(OID_TAPI_DEV_SPECIFIC);
        OID_CASE(OID_TAPI_DIAL);
        OID_CASE(OID_TAPI_DROP);
        OID_CASE(OID_TAPI_GET_ADDRESS_CAPS);
        OID_CASE(OID_TAPI_GET_ADDRESS_ID);
        OID_CASE(OID_TAPI_GET_ADDRESS_STATUS);
        OID_CASE(OID_TAPI_GET_CALL_ADDRESS_ID);
        OID_CASE(OID_TAPI_GET_CALL_INFO);
        OID_CASE(OID_TAPI_GET_CALL_STATUS);
        OID_CASE(OID_TAPI_GET_DEV_CAPS);
        OID_CASE(OID_TAPI_GET_DEV_CONFIG);
        OID_CASE(OID_TAPI_GET_EXTENSION_ID);
        OID_CASE(OID_TAPI_GET_ID);
        OID_CASE(OID_TAPI_GET_LINE_DEV_STATUS);
        OID_CASE(OID_TAPI_MAKE_CALL);
        OID_CASE(OID_TAPI_NEGOTIATE_EXT_VERSION);
        OID_CASE(OID_TAPI_OPEN);
        OID_CASE(OID_TAPI_PROVIDER_INITIALIZE);
        OID_CASE(OID_TAPI_PROVIDER_SHUTDOWN);
        OID_CASE(OID_TAPI_SECURE_CALL);
        OID_CASE(OID_TAPI_SELECT_EXT_VERSION);
        OID_CASE(OID_TAPI_SEND_USER_USER_INFO);
        OID_CASE(OID_TAPI_SET_APP_SPECIFIC);
        OID_CASE(OID_TAPI_SET_CALL_PARAMS);
        OID_CASE(OID_TAPI_SET_DEFAULT_MEDIA_DETECTION);
        OID_CASE(OID_TAPI_SET_DEV_CONFIG);
        OID_CASE(OID_TAPI_SET_MEDIA_MODE);
        OID_CASE(OID_TAPI_SET_STATUS_MESSAGES);
		OID_CASE(OID_TAPI_TRANSLATE_ADDRESS);
        OID_CASE(OID_WAN_CURRENT_ADDRESS);
        OID_CASE(OID_WAN_GET_BRIDGE_INFO);
        OID_CASE(OID_WAN_GET_COMP_INFO);
        OID_CASE(OID_WAN_GET_INFO);
        OID_CASE(OID_WAN_GET_LINK_INFO);
        OID_CASE(OID_WAN_GET_STATS_INFO);
        OID_CASE(OID_WAN_HEADER_FORMAT);
        OID_CASE(OID_WAN_LINE_COUNT);
        OID_CASE(OID_WAN_MEDIUM_SUBTYPE);
        OID_CASE(OID_WAN_PERMANENT_ADDRESS);
        OID_CASE(OID_WAN_PROTOCOL_TYPE);
        OID_CASE(OID_WAN_QUALITY_OF_SERVICE);
        OID_CASE(OID_WAN_SET_BRIDGE_INFO);
        OID_CASE(OID_WAN_SET_COMP_INFO);
        OID_CASE(OID_WAN_SET_LINK_INFO);

        default:
            OidName = "Unknown OID";
            break;
    }
    return OidName;
}
#endif

DWORD
DoNDISRegisterProtocol()
{
    NDIS_STATUS Status;         // Status for NDIS calls.
	
	DEBUGMSG (ZONE_TRACE, (TEXT("+DoNDISRegisterProtocol\r\n")));
	
	NdisRegisterProtocol(&Status, &v_PROTHandle,
						 (NDIS_PROTOCOL_CHARACTERISTICS *)
						 &PROTCharacteristics, sizeof(PROTCharacteristics));

	if (Status != NDIS_STATUS_SUCCESS)
	{
		DEBUGMSG (ZONE_TRACE,
				  (TEXT(" pppMac_Initialize: Error %d from NdisRegisterProtocol\r\n"),
				   Status));
		return ERROR_EVENT_INVALID;
	}

	return SUCCESS;
}

//** PROTOAComplete - PROT Open adapter complete handler.
//
//  This routine is called by the NDIS driver when an open adapter
//  call completes. Presumably somebody is blocked waiting for this, so
//  we'll wake him up now.
//
//  Entry:
//      Handle - The binding handle we specified (really a pointer to an AI).
//      Status - Final status of command.
//      ErrorStatus - Final error status.
//
//  Exit: Nothing.
//
void NDIS_API
PROTOAComplete(NDIS_HANDLE Handle, NDIS_STATUS Status, NDIS_STATUS ErrorStatus)
{
//    PROTInterface    *ai = (PROTInterface *)Handle;   // For compiler.
	
	DEBUGMSG (ZONE_FUNCTION, (TEXT("+PROTOAComplete(0x%X, 0x%X, 0x%X)\r\n"),
							   Handle, Status, ErrorStatus));	

//    CTESignal(&ai->ai_block, (uint)Status);         // Wake him up, and return status.
	DEBUGMSG (ZONE_FUNCTION, (TEXT("-PROTOAComplete:\r\n"), Handle, Status, ErrorStatus));	

}
//** PROTCAComplete - PROT close adapter complete handler.
//
//  This routine is called by the NDIS driver when a close adapter
//  request completes.
//
//  Entry:
//      Handle - The binding handle we specified (really a pointer to an AI).
//      Status - Final status of command.
//
//  Exit: Nothing.
//
void NDIS_API
PROTCAComplete(
	IN	NDIS_HANDLE Handle,
	IN	NDIS_STATUS Status)
{
	DWORD i;

	PNDISWAN_ADAPTER	pAdapter = (PNDISWAN_ADAPTER)Handle;

	DEBUGMSG (ZONE_FUNCTION, (TEXT("PPP: +PROTCAComplete(0x%X, 0x%X)\r\n"),Handle, Status));

	DEBUGMSG(ZONE_MAC || (ZONE_ERROR && Status), (TEXT("PPP: NdisCloseAdapter %s Complete Status=%x\n"), pAdapter->szAdapterName, Status));

	if (pAdapter->hUnbindContext)
	{
		//
		//	The CloseAdapter was initiated by a call to our UnbindAdapter Handler, from
		//	which we returned NDIS_STATUS_PENDING.  We now invoke the completion handler.
		//
		DEBUGMSG(ZONE_MAC, (TEXT("PPP: Completing Unbind for adapter %s Complete Status=%x\n"), pAdapter->szAdapterName, Status));
		NdisCompleteUnbindAdapter(pAdapter->hUnbindContext, Status);
	}

	for (i = 0; i < pAdapter->dwNumDevices; i++)
	{
		LocalFree(pAdapter->pDeviceInfo[i].pwszDeviceName);
	}
	pppFreeMemory (pAdapter->pDeviceInfo,   pAdapter->dwNumDevices * sizeof(*pAdapter->pDeviceInfo));
	pppFreeMemory (pAdapter->szAdapterName, (wcslen(pAdapter->szAdapterName)+1)*sizeof(WCHAR));
	pppFreeMemory (pAdapter, sizeof (NDISWAN_ADAPTER));

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

//** PROTSendComplete - PROT send complete handler.
//
//  This routine is called by the NDIS driver when a send completes.
//  This is a pretty time critical operation, we need to get through here
//  quickly. We'll strip our buffer off and put it back, and call the upper
//  later send complete handler.
//
//  Entry:
//      Handle - The binding handle we specified (really a pointer to an AI).
//      Packet - A pointer to the packet that was sent.
//      Status - Final status of command.
//
//  Exit: Nothing.
//
void NDIS_API
PROTSendComplete(
	NDIS_HANDLE      Handle,
	PNDIS_WAN_PACKET pPacket,
	NDIS_STATUS      Status)
{
	//
	// The Handle is pretty useless since it refers to the miniport
	// adapter binding and not to the particular active session. So,
	// we need to get our pMac via the packet. In pppMac_GetPacket
	// we saved our pMac in the packet's ProtocolReserved1 field.
	//
	macCntxt_t	 *pMac = (macCntxt_t *)pPacket->ProtocolReserved1;
	pppSession_t *pSession;

	DEBUGMSG(ZONE_MAC || (ZONE_ERROR && Status), (L"PPP: ProtSendComplete: pPacket=%x Status=%x\n", pPacket, Status));

	pSession = PPPADDREFMAC(pMac, REF_SEND_COMPLETE);
	if (pSession)
	{
		NdisWanFreePacket(pMac, pPacket);
		PPPDELREF(pSession, REF_SEND_COMPLETE);
	}
}

//** PROTTDComplete - PROT transfer data complete handler.
//
//  This routine is called by the NDIS driver when a transfer data
//  call completes. Since we never transfer data ourselves, this must be
//  from the upper layer. We'll just call his routine and let him deal
//  with it.
//
//  Entry:
//      Handle - The binding handle we specified (really a pointer to an AI).
//      Packet - A pointer to the packet used for the TD.
//      Status - Final status of command.
//      BytesCopied - Count of bytes copied.
//
//  Exit: Nothing.
//
void NDIS_API
PROTTDComplete(NDIS_HANDLE Handle, PNDIS_PACKET Packet, NDIS_STATUS Status,
    uint BytesCopied)
{
//    PROTInterface    *ai = (PROTInterface *)Handle;

	DEBUGMSG (ZONE_FUNCTION, (TEXT("+PROTTDComplete(0x%X, 0x%X, 0x%X, %d)\r\n"),
							   Handle, Packet, Status, BytesCopied));
//    IPTDComplete(ai->ai_context, Packet, Status, BytesCopied);

}

//** PROTResetComplete - PROT reset complete handler.
//
//  This routine is called by the NDIS driver when a reset completes.
//
//  Entry:
//      Handle - The binding handle we specified (really a pointer to an AI).
//      Status - Final status of command.
//
//  Exit: Nothing.
//
void NDIS_API
PROTResetComplete(NDIS_HANDLE Handle, NDIS_STATUS Status)
{
	DEBUGMSG (ZONE_FUNCTION, (TEXT("+PROTResetComplete(0x%X, 0x%X)\r\n"),
							   Handle, Status));
}

VOID
PppNdisFreeRequest(
	PNDIS_REQUEST_BETTER	pRequest)
{
	// This is to be used during calls using an event, not a callback func
	ASSERT (pRequest->pCompletionFunc == NULL);

	// Free the event
	NdisFreeEvent(&pRequest->Event);

	// Free the request
	DEBUGMSG(ZONE_ALLOC, (TEXT("PPP: PppNdisFreeRequest Free pRequest=%x\n"), pRequest));
	pppFreeMemory(pRequest, sizeof(*pRequest));
}

VOID
PppNdisRequestCompleteCb(
	PNDIS_REQUEST_BETTER	pRequest,
	NDIS_STATUS				Status
	)
//
//	This function is called when an NDIS request has completed.
//	A request is completed when:
//		Synchronously:  NdisRequest returns a status other than PENDING
//		Asynchronously: NdisRequest returns PENDING and the Protocol Request Complete Handler is called
//
{
	//
    // Call the completion function if there is one.
    // Having a completion function and blocking against the
    // event are mutually exclusive,
    //

    if( pRequest->pCompletionFunc != NULL )
    {
		if (pRequest->pSession)
			pppLock(pRequest->pSession);

        (*pRequest->pCompletionFunc)(pRequest, pRequest->FuncArg, Status);

		if (pRequest->pSession)
		{
			pppUnLock(pRequest->pSession);

			// Delete the session reference taken in PppNdisIssueRequest to
			// prevent it from going away while request was in progress
			PPPDELREF(pRequest->pSession, REF_ISSUEREQUEST);
		}

		// Free the request
		DEBUGMSG(ZONE_ALLOC, (TEXT("PPP: PppNdisRequestCompleteCb Free pRequest=%x\n"), pRequest));
		pppFreeMemory(pRequest, sizeof(*pRequest));
    }
    else // Requesting thread is blocked on event
    {
		// Communicate final status to blocked caller
		pRequest->Status = Status;
		NdisSetEvent( &pRequest->Event );

		// We can't free the request since we're using it to
		// return the Status to the thread blocked on the event.
		// The waiting thread must free
		// the event and the request by calling PppNdisFreeRequest.
    }
}

VOID
PROTRequestComplete(
    IN  NDIS_HANDLE         ProtocolBindingContext,
    IN  PNDIS_REQUEST       NdisRequest,
    IN  NDIS_STATUS         Status
    )
/*++

Routine Description:

    Completion handler for the previously posted request.

⌨️ 快捷键说明

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