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

📄 mac.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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.
//
/*****************************************************************************
* 
*
*   @doc EX_RAS
*   mac.c	Mac Layer interface
*
*   Date: 2/25/99
*
*/


//  Include Files

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

#define TAPI_DEVICECLASS_NAME       TEXT("tapi/line")

// ----------------------------------------------------------------
//
//	Global Data
//
// ----------------------------------------------------------------
NDIS_HANDLE v_PROTHandle;      // Our NDIS protocol handle.
HANDLE				v_hRequestEvent;
CRITICAL_SECTION	v_RequestCS;
NDIS_STATUS			v_RequestStatus;
PNDISWAN_ADAPTER	v_AdapterList;
CRITICAL_SECTION	v_AdapterCS;

DWORD
pppMac_NdisToRasErrorCode(
	DWORD	dwNdisErrorCode)
//
//	Translate an NDIS error code returned by the miniport driver
//	into a RAS error code.
//
{
	DWORD	dwRasErrorCode;

	switch(dwNdisErrorCode)
	{
		case NDIS_STATUS_SUCCESS:
			dwRasErrorCode = ERROR_SUCCESS;
			break;

		case NDIS_STATUS_CLOSED:
			dwRasErrorCode = ERROR_PORT_NOT_OPEN;
			break;

		case NDIS_STATUS_TAPI_CALLUNAVAIL:
		case NDIS_STATUS_TAPI_RESOURCEUNAVAIL:
			dwRasErrorCode = ERROR_PORT_NOT_AVAILABLE;
			break;

		case NDIS_STATUS_FAILURE:
		case NDIS_STATUS_INVALID_OID:
			dwRasErrorCode = ERROR_UNKNOWN;
			break;

		case NDIS_STATUS_TAPI_INVALPARAM:
			dwRasErrorCode = ERROR_WRONG_INFO_SPECIFIED;
			break;

		case NDIS_STATUS_TAPI_NODEVICE:
						dwRasErrorCode = ERROR_DEVICE_NOT_READY;
			break;

		case NDIS_STATUS_TAPI_NODRIVER:
			dwRasErrorCode = ERROR_DEVICE_NOT_READY;
			break;

		case NDIS_STATUS_TAPI_OPERATIONUNAVAIL:
			dwRasErrorCode = ERROR_DEVICE_NOT_READY;
			break;

		case NDIS_STATUS_RESOURCES:
			dwRasErrorCode = ERROR_NOT_ENOUGH_MEMORY;
			break;

		case NDIS_STATUS_TAPI_INCOMPATIBLEEXTVERSION:
			dwRasErrorCode = ERROR_UNKNOWN;
			break;

		case NDIS_STATUS_TAPI_INVALLINESTATE:
			dwRasErrorCode = ERROR_PORT_NOT_CONFIGURED;
			break;

		case NDIS_STATUS_TAPI_INUSE:
			dwRasErrorCode = ERROR_PORT_ALREADY_OPEN;
			break;

		default:
			//
			// All error types that the miniport returns should be
			// covered explicitly.  If any are not, they will be caught here
			// and can have a case added.
			//
			DEBUGMSG(ZONE_ERROR, (TEXT("PPP: pppMac_NdisToRasErrorCode doesn't know error %x\n"), dwNdisErrorCode));
			dwRasErrorCode = ERROR_UNKNOWN;
			break;
	}

	return dwRasErrorCode;
}

DWORD
pppMac_Initialize()
{
	DWORD	dwRetVal;
	
	DEBUGMSG (ZONE_TRACE, (TEXT("+pppMac_Initialize\r\n")));

	v_hRequestEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
    InitializeCriticalSection (&v_RequestCS);
    InitializeCriticalSection (&v_AdapterCS);

	if (dwRetVal = DoNDISRegisterProtocol())
	{
		CloseHandle (v_hRequestEvent);
		return dwRetVal;
	}

	// Note that adapters are dynamically bound via the
	// PROTBindAdapter callback.  No static initialization
	// takes place here.
	
	return SUCCESS;
}

#define COUNTOF(array) (sizeof(array) / sizeof(array[0]))

DWORD
pppMac_InstanceCreate (
	void *SessionContext, 
	void **ReturnedContext,
	LPCTSTR szDeviceName,
	LPCTSTR szDeviceType)
{
	NDIS_STATUS		Status;
	macCntxt_t		*pMac;
	
	DEBUGMSG (ZONE_FUNCTION, (TEXT("!pppMac_InstanceCreate devName=%s devType=%s\n"), szDeviceName, szDeviceType));
	
	// Allocate our context structure.
	pMac = (macCntxt_t *)pppAllocateMemory(sizeof (macCntxt_t));

	if (NULL == pMac) {
		return ERROR_NOT_ENOUGH_MEMORY;
	}

	pMac->session = SessionContext;
	
	pMac->bCallCloseRequested = FALSE;
	pMac->bCallClosed = TRUE;
	pMac->bLineCloseRequested = FALSE;
	pMac->bLineClosed = TRUE;

	pMac->bMacStatsObtained = FALSE;

	pMac->dwLineCallState = LINECALLSTATE_IDLE;

	StringCchCopyW(pMac->szDeviceName, COUNTOF(pMac->szDeviceName), szDeviceName);
	StringCchCopyW(pMac->szDeviceType, COUNTOF(pMac->szDeviceType), szDeviceType);

	(NDIS_HANDLE)pMac->hCall = INVALID_HANDLE_VALUE;
	(NDIS_HANDLE)pMac->hLine = INVALID_HANDLE_VALUE;

	if (SUCCESS != FindAdapter (szDeviceName, szDeviceType, &(pMac->pAdapter),
								&(pMac->dwDeviceID))) {
		DEBUGMSG (ZONE_ERROR, (TEXT("PPP: Can't find device '%s'\n"), szDeviceName));
		pppFreeMemory (pMac, sizeof (macCntxt_t));
		return ERROR_DEVICE_DOES_NOT_EXIST;
	}

	//
	//	Do not allow new connections on an adapter from which we are unbinding.
	//
	if (pMac->pAdapter->bClosingAdapter)
	{
		DEBUGMSG (ZONE_ERROR, (TEXT("PPP: No new connections on '%s' allowed due to adapter close in progress\n"), pMac->szDeviceName));
		AdapterDelRef(pMac->pAdapter);
		pppFreeMemory (pMac, sizeof (macCntxt_t));
		return ERROR_DEVICE_DOES_NOT_EXIST;
	}

	DEBUGMSG (ZONE_TRACE, (TEXT("pppMac_InstanceCreate: Found DeviceID %d\r\n"),
						   pMac->dwDeviceID));

	pMac->pPendingLineCloseCompleteList = NULL;
	pMac->pPendingCallDropCompleteList = NULL;
	pMac->pPendingCallCloseCompleteList = NULL;
	
	PppNdisDoSyncRequest (&Status,
							pMac->pAdapter,
							NdisRequestQueryInformation,
							OID_WAN_GET_INFO,
							&(pMac->WanInfo),
							sizeof(pMac->WanInfo));

	if (Status != NDIS_STATUS_SUCCESS)
	{
		DEBUGMSG (ZONE_ERROR,
				  (TEXT(" pppMac_InstanceCreate: Error 0x%X from OID_WAN_GET_INFO\r\n"),
				   Status));
		AdapterDelRef (pMac->pAdapter);
		pppFreeMemory (pMac, sizeof (macCntxt_t));
		return ERROR_DEVICE_DOES_NOT_EXIST;
	}

	pMac->hNdisTapiEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
	pMac->hEventLineOpenComplete = CreateEvent (NULL, TRUE, FALSE, NULL);
	if (pMac->hNdisTapiEvent == NULL || pMac->hEventLineOpenComplete == NULL)
	{
		DEBUGMSG (ZONE_ERROR, (TEXT("PPP: ERROR - pppMac_InstanceCreate CreateEvent failed\n")));
		return ERROR_NOT_ENOUGH_MEMORY;
	}

	NdisAllocateSpinLock (&pMac->PacketLock);

	Status = NdisWanAllocateSendResources (pMac);

	if (NDIS_STATUS_SUCCESS != Status) {
		// This will do the AdapterDelRef()
		pppMac_InstanceDelete (pMac);
		return Status;
	}
	
	*ReturnedContext = pMac;
	
	DEBUGMSG(ZONE_MAC, (L"PPP: Created MAC %x adapter=%s %x refcnt=%d\n", pMac, pMac->pAdapter->szAdapterName, pMac->pAdapter, pMac->pAdapter->dwRefCnt));

	return 0;
}

void
pppMac_GetFramingInfo(
	IN	PVOID	context,
	OUT	PDWORD	pFramingBits,
	OUT	PDWORD	pDesiredACCM)
{
	macCntxt_t		*pMac = (macCntxt_t *)context;

	*pFramingBits = pMac->WanInfo.FramingBits;
	*pDesiredACCM = pMac->WanInfo.DesiredACCM;
}

DWORD
pppMac_LineOpen(
	void *context)
{
	macCntxt_t		*pMac = (macCntxt_t *)context;
	DWORD			dwRetVal;

	// Configure device specific parameter settings, if any
	if (((pppSession_t *)(pMac->session))->lpbDevConfig != NULL)
	{
		NdisTapiSetDevConfig (pMac);
	}

	// Open the line
	dwRetVal = NdisTapiLineOpen (pMac);
	return pppMac_NdisToRasErrorCode(dwRetVal);
}

DWORD
pppMac_LineListen(
	void *context)
//
//	Listen for incoming connections on the specified line.
//
{
	macCntxt_t		*pMac = (macCntxt_t *)context;
	DWORD			dwRetVal;

	dwRetVal = NdisTapiSetDefaultMediaDetection(pMac, LINEMEDIAMODE_DIGITALDATA | LINEMEDIAMODE_DATAMODEM);
	return pppMac_NdisToRasErrorCode(dwRetVal);
}

static void
pppHangupComplete(
	PVOID	pData)
{
	HANDLE			hHangupCompleteEvent = (HANDLE)pData;

    DEBUGMSG( ZONE_FUNCTION, ( TEXT( "PPP:+pppHangupComplete\n" ) ));

	SetEvent(hHangupCompleteEvent);

    DEBUGMSG( ZONE_FUNCTION, ( TEXT( "PPP:-pppHangupComplete\n" ) ));
}

//
//	Custom Scripting Dll Support functions
//

DWORD
RasGetBuffer(
		OUT	PBYTE *   ppBuffer,
	IN	OUT	PDWORD    pdwSize)
//
//	The custom-scripting DLL calls RasGetBuffer to allocate memory
//	for sending or receiving data over the port connected to the server.
//
//	Return values
//	If the function succeeds, the return value is ERROR_SUCCESS.
//
//	If the function fails, the return value is the following error code.
//
//	ERROR_OUT_OF_BUFFERS	-	RAS cannot allocate anymore buffer space.
//
{
	DWORD	dwResult = ERROR_SUCCESS;

	// To simplify buffer management, always allocate max size buffers.
	*pdwSize = MAX_CUSTOM_SCRIPT_RX_BUFFER_SIZE;

	*ppBuffer = pppAllocateMemory(*pdwSize);
	if (*ppBuffer == NULL)
	{
		dwResult = ERROR_OUT_OF_BUFFERS;
		DEBUGMSG( ZONE_FUNCTION, ( TEXT( "PPP:ERROR in RasGetBuffer %d byte alloc, error = %x\n" ), *pdwSize, GetLastError() ));
	}

	return dwResult;
}

DWORD
RasFreeBuffer(
	IN	PBYTE	pBuffer)
//
//	The custom-scripting DLL calls RasFreeBuffer to release a
//	memory buffer that was allocated by a previous call to RasGetBuffer
//
//	Return values
//	If the function succeeds, the return value is ERROR_SUCCESS.
//
//	If the function fails, the return value is the following error code.
//
//	ERROR_BUFFER_INVALID		- The pointer to the buffer passed in the
//								  pBuffer parameter is invalid.
//
{
	DWORD	dwResult = ERROR_SUCCESS;

	pppFreeMemory(pBuffer, MAX_CUSTOM_SCRIPT_RX_BUFFER_SIZE);

	return dwResult;
}

DWORD
RasSendBuffer(
	IN	HANDLE    hPort,
	IN	PBYTE     pBuffer,
	IN	DWORD     dwSize)
//
//	The custom-scripting DLL calls the RasSendBuffer function
//	to send data to the server over the specified port.
//
//	Return values
//	If the function succeeds, the return value is ERROR_SUCCESS.
//	If the function fails, the return value can be one of the following error codes.
//	
//	Value						Meaning 
//	ERROR_BUFFER_INVALID		The pointer to the buffer passed in the pBuffer parameter is invalid. 
//	ERROR_INVALID_PORT_HANDLE	The handle specified by the hPort parameter is invalid.
//
{
	macCntxt_t		*pMac = (macCntxt_t *)hPort;
	DWORD			dwResult = ERROR_SUCCESS,
					dwBytesSent,
					bytesWritten;

	for (dwBytesSent = 0;
		 dwBytesSent < dwSize;
		 dwBytesSent += bytesWritten)
	{
		if (!WriteFile (pMac->hComPort, pBuffer + dwBytesSent, dwSize - dwBytesSent, &bytesWritten, 0)
		||  bytesWritten == 0)
		{
			dwResult = GetLastError();
			DEBUGMSG(ZONE_ERROR, (
				TEXT( "PPP: ERROR RasSendBuffer-WriteFile Error %d Aborting Packet after sending %d of %d bytes\n" ),
				dwResult, dwBytesSent, dwSize) );
			break;
		}
	}

	return dwResult;
}

DWORD
RasRetrieveBuffer(
	IN	HANDLE    hPort,
	OUT	PBYTE     pBuffer,
	OUT	PDWORD    pdwBytesRead)
//
//	The custom-scripting DLL calls the RasRetrieveBuffer function
//	to obtain data received from the RAS server over the specified port.
//	The custom-scripting DLL should call RasRetrieveBuffer only after
//	RAS has signaled the event object passed in the call to RasReceiveBuffer.
//
//	Return values
//	If the function succeeds, the return value is ERROR_SUCCESS.
//	
//	If the function fails, the return value can be one of the following error codes.
//	
//	Value						Meaning 
//	ERROR_BUFFER_INVALID		The pointer to the buffer passed in the pBuffer parameter is invalid. 
//	ERROR_INVALID_PORT_HANDLE	The handle specified by the hPort parameter is invalid.
//
{
	macCntxt_t		*pMac = (macCntxt_t *)hPort;
	DWORD			dwResult = ERROR_SUCCESS;

	if (ReadFile(pMac->hComPort, pBuffer, MAX_CUSTOM_SCRIPT_RX_BUFFER_SIZE, pdwBytesRead, 0 ) == FALSE)
	{
		// Serial functions will return an error if a PCMCIA card has
		// been removed. If the error is INVALID_HANDLE or GEN_FAILURE
		// the PCMCIA card was removed. In this case the MAC layer is
		// down.

		dwResult = GetLastError();
		DEBUGMSG(ZONE_ERROR, (TEXT( "PPP:RasRetrieveBuffer ReadFile failed %d\n"), dwResult));
	}

	return dwResult;
}

DWORD WINAPI
rasReceiveEventThread (
	IN	LPVOID pVArg)
{
	macCntxt_t		*pMac = (macCntxt_t *)pVArg;
	DWORD			dwMask;

	DEBUGMSG( ZONE_FUNCTION, (TEXT( "PPP: +rasReceiveEventThread\n") ));

	while ( WaitCommEvent(pMac->hComPort, &dwMask, NULL ) == TRUE )
	{
		if (dwMask & (EV_POWER | EV_RLSD))
		{
			// Line down
			DEBUGMSG(ZONE_ERROR, (TEXT( "PPP:rasReceiveEventThread - LINE DOWN eventmask=%x\n"), dwMask));
		}
		else if (dwMask & EV_RXCHAR)
		{
			// Data ready to be read
			DEBUGMSG(ZONE_ERROR, (TEXT( "PPP:rasReceiveEventThread - EV_RXCHAR\n"), dwMask));
		}

		//
		//	Signal the custom dll script to call RasRetrieveBuffer to read any rx data
		//
		SetEvent(pMac->hRxEvent);

		//
		//	Paranoia?  In case WaitCommEvent returns for pending rx data instead of
		//  waiting for new rx data.
		//
		Sleep(50);
	}

	DEBUGMSG( ZONE_FUNCTION, (TEXT( "PPP: -rasReceiveEventThread\n") ));
	return 0;
}

DWORD
RasReceiveBuffer(
	IN	HANDLE    hPort,
	OUT	PBYTE     pBuffer,
	OUT	PDWORD    pdwSize,
	IN	DWORD     dwTimeoutMilliseconds,
	IN	HANDLE    hEvent)
//
//	The custom-scripting DLL calls the RasReceiveBuffer function
//	to inform RAS that it is ready to receive data from the server over the specified port.
//
//	Return values
//	If the function succeeds, the return value is ERROR_SUCCESS.
//	
//	If the function fails, the return value can be one of the following error codes.
//	
//	Value						Meaning 
//	ERROR_BUFFER_INVALID		The pointer to the buffer passed in the pBuffer parameter is invalid. 
//	ERROR_INVALID_PORT_HANDLE	The handle specified by the hPort parameter is invalid.
//
{
	macCntxt_t		*pMac = (macCntxt_t *)hPort;
	DWORD			dwResult = ERROR_SUCCESS,
					dwID;
	COMMTIMEOUTS	CommTimeouts;

	do
	{
		if (SetCommMask(pMac->hComPort, EV_RXCHAR | EV_RLSD | EV_POWER ) == FALSE)
		{
			dwResult = GetLastError();
			break;
		}

⌨️ 快捷键说明

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