miniport.cpp

来自「pppoe client」· C++ 代码 · 共 663 行 · 第 1/2 页

CPP
663
字号

//********************************************************************
//	日期:	2004/08/25 - 25:8:2004   1:44
//	名前:	tiamo
//	描述:	miniport
//*********************************************************************

#include "Stdafx.h"

#pragma alloc_text(PAGE,miniportInitialize)
#pragma alloc_text(PAGE,miniportHalt)

// miniport init
NDIS_STATUS miniportInitialize(PNDIS_STATUS pOpenErrorStatus,PUINT puSelectedMediumIndex,PNDIS_MEDIUM pMediumArray,
							   UINT uMediumArraySize,NDIS_HANDLE hAdapterHandle,NDIS_HANDLE hConfigurationContext)
{
	PAGED_CODE();

	NDIS_STATUS status = NDIS_STATUS_SUCCESS;

	__try
	{
		// select cowan medium
		UINT i;
		for(i = 0; i < uMediumArraySize; i ++)
		{
			if(pMediumArray[i] == NdisMediumCoWan)
			{
				*puSelectedMediumIndex = i;
				break;
			}
		}

		// check
		if(i == uMediumArraySize)
		{
			DebugError(("unable to select cowan medium.\n"));
			ExRaiseStatus(status = NDIS_STATUS_UNSUPPORTED_MEDIA);
		}

		// allocate adapter
		g_pAdapter = CreateAdapter();

		// init adapter
		status = InitializeAdapter(g_pAdapter,hAdapterHandle,hConfigurationContext);

		if(status != NDIS_STATUS_SUCCESS)
		{
			DebugError(("unable to init adapter.\n"));
			ExRaiseStatus(status);
		}

		// register address family
		CO_ADDRESS_FAMILY mcmAf;
		mcmAf.AddressFamily = CO_ADDRESS_FAMILY_TAPI_PROXY;
		mcmAf.MajorVersion = NDIS_MAJOR_VERSION;
		mcmAf.MinorVersion = NDIS_MINOR_VERSION;

		NDIS_CALL_MANAGER_CHARACTERISTICS mcmChar;
		NdisZeroMemory(&mcmChar,sizeof(mcmChar));
		mcmChar.MajorVersion = NDIS_MAJOR_VERSION;
		mcmChar.MinorVersion = NDIS_MINOR_VERSION;

		mcmChar.CmActivateVcCompleteHandler = (CM_ACTIVATE_VC_COMPLETE_HANDLER)mcmActivateVcComplete;
		mcmChar.CmCloseAfHandler = (CM_CLOSE_AF_HANDLER)mcmCloseAf;
		mcmChar.CmCloseCallHandler = (CM_CLOSE_CALL_HANDLER)mcmCloseCall;
		mcmChar.CmCreateVcHandler = (CO_CREATE_VC_HANDLER)mcmCreateVc;
		mcmChar.CmDeactivateVcCompleteHandler = (CM_DEACTIVATE_VC_COMPLETE_HANDLER)mcmDeactivateVcComplete;
		mcmChar.CmDeleteVcHandler = (CO_DELETE_VC_HANDLER)mcmDeleteVc;
		mcmChar.CmDeregisterSapHandler = (CM_DEREG_SAP_HANDLER)mcmDeregisterSap;
		mcmChar.CmIncomingCallCompleteHandler = (CM_INCOMING_CALL_COMPLETE_HANDLER)mcmIncomingCallComplete;
		mcmChar.CmMakeCallHandler = (CM_MAKE_CALL_HANDLER)mcmMakeCall;
		mcmChar.CmModifyCallQoSHandler = (CM_MODIFY_CALL_QOS_HANDLER)mcmModifyCallQos;
		mcmChar.CmOpenAfHandler = (CM_OPEN_AF_HANDLER)mcmOpenAf;
		mcmChar.CmRegisterSapHandler = (CM_REG_SAP_HANDLER)mcmRegisterSap;
		mcmChar.CmRequestCompleteHandler = (CO_REQUEST_COMPLETE_HANDLER)mcmRequestComplete;
		mcmChar.CmRequestHandler= (CO_REQUEST_HANDLER)mcmRequest;

		status = NdisMCmRegisterAddressFamily(hAdapterHandle,&mcmAf,&mcmChar,sizeof(mcmChar));
		if(status != NDIS_STATUS_SUCCESS)
		{
			DebugError(("register af error 0x%x.\n",status));
			ExRaiseStatus(status);
		}

		NdisMSetAttributesEx(hAdapterHandle,g_pAdapter,0,
							 NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT	|
							 NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT	|
							 NDIS_ATTRIBUTE_DESERIALIZE				|
							 NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND,
							 NdisInterfaceInternal);
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		miniportHalt(g_pAdapter);

		if(status == NDIS_STATUS_SUCCESS)
			status = NDIS_STATUS_FAILURE;
	}

	return status;
}

// miniport halt
VOID miniportHalt(PADAPTER pAdapter)
{
	PAGED_CODE();

	ASSERT(pAdapter == g_pAdapter);

	ShutdownAdapter(pAdapter);
}

// reset
NDIS_STATUS miniportReset(PBOOLEAN pbAddressingReset,PADAPTER pAdapter)
{
	return NDIS_STATUS_NOT_RESETTABLE;
}

// send packet
VOID miniportCoSendPackets(PCHANNEL pChannel,PPNDIS_PACKET pPacketArray,UINT uNumberOfPackets)
{
	UINT i = 0;
	__try
	{
		for(; i < uNumberOfPackets; i ++)
		{
			// build packet
			PPACKET pPacket = BuildPacketForSend(pChannel,pPacketArray[i]);

			// reference the packet,ref = 2
			ReferencePacket(pPacket);
		
			// ref bind,protocol's send complete will deref the bind
			ReferenceBind(pChannel->m_pBindContext,TRUE);

			// send it
			SendPacket(pChannel->m_pBindContext,pPacket);

			// deref packet,ref = 1, the protocol's send complete routine will deref the packet
			DereferencePacket(pPacket);
		}
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		// ndis say that we must call send complete for every packet
		for( ;i < uNumberOfPackets; i ++)
		{
			NdisMCoSendComplete(NDIS_STATUS_FAILURE,pChannel->m_hNdisVcHandle,pPacketArray[i]);
		}
	}
}

// return packet,which we indicate to upper,just ref the packet
VOID miniportReturnPacket(PADAPTER pAdapter,PNDIS_PACKET pNdisPacket)
{
	ASSERT(pAdapter && pAdapter == g_pAdapter && pAdapter->m_ulSig == ADAPTER_SIG);

	PMINIPORT_RESERVED pResv = reinterpret_cast<PMINIPORT_RESERVED>(pNdisPacket->MiniportReservedEx);

	ASSERT(pResv && pResv->m_pChannel && pResv->m_pPacket && pResv->m_pChannel->m_ulSig == CHANNEL_SIG);

	NdisInterlockedDecrement(&pResv->m_pChannel->m_lPendingReturnPackets);

	DereferencePacket(pResv->m_pPacket);
}

// miniport corequest
NDIS_STATUS miniportCoRequest(PADAPTER pAdapter,PCHANNEL pChannel,PNDIS_REQUEST pNdisRequest)
{
	ASSERT(pAdapter && pAdapter == g_pAdapter && pAdapter->m_ulSig == ADAPTER_SIG);

	NDIS_STATUS status;

	switch(pNdisRequest->RequestType)
	{
	case NdisRequestQueryInformation:
	case NdisRequestQueryStatistics:
		status = QueryRequest(pChannel,pNdisRequest->DATA.QUERY_INFORMATION.Oid,
							  pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,
							  pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength,
							  &pNdisRequest->DATA.QUERY_INFORMATION.BytesWritten,
							  &pNdisRequest->DATA.QUERY_INFORMATION.BytesNeeded);
		break;

	case NdisRequestSetInformation:
		status = SetRequest(pChannel,pNdisRequest->DATA.QUERY_INFORMATION.Oid,
							pNdisRequest->DATA.SET_INFORMATION.InformationBuffer,
							pNdisRequest->DATA.SET_INFORMATION.InformationBufferLength,
							&pNdisRequest->DATA.SET_INFORMATION.BytesRead,
							&pNdisRequest->DATA.SET_INFORMATION.BytesNeeded);

		break;

	default:
		status = NDIS_STATUS_NOT_SUPPORTED;
		break;
	}

	return status;
}

// miniport coactivate vc
NDIS_STATUS miniportCoActivateVc(PCHANNEL pChannel,PCO_CALL_PARAMETERS pCallParameters)
{
	return NDIS_STATUS_SUCCESS;
}

// miniport codeactivate vc
NDIS_STATUS miniportCoDeactivateVc(PCHANNEL pChannel)
{
	return NDIS_STATUS_SUCCESS;
}

namespace
{
	NDIS_OID _s_supported[] = 
	{
		OID_GEN_CO_SUPPORTED_LIST,
		OID_GEN_CO_HARDWARE_STATUS,
		OID_GEN_CO_MEDIA_SUPPORTED,
		OID_GEN_CO_MEDIA_IN_USE,
		OID_GEN_CO_LINK_SPEED,
		OID_GEN_CO_VENDOR_ID,
		OID_GEN_CO_VENDOR_DESCRIPTION,
		OID_GEN_CO_DRIVER_VERSION,
		OID_GEN_CO_PROTOCOL_OPTIONS,
		OID_GEN_CO_MAC_OPTIONS,
		OID_GEN_CO_MEDIA_CONNECT_STATUS,
		OID_GEN_CO_VENDOR_DRIVER_VERSION,
		OID_GEN_CO_SUPPORTED_GUIDS,

		OID_CO_TAPI_CM_CAPS,
		OID_CO_TAPI_LINE_CAPS,
		OID_CO_TAPI_ADDRESS_CAPS,

		OID_802_3_PERMANENT_ADDRESS,
		OID_802_3_CURRENT_ADDRESS,

		OID_WAN_PERMANENT_ADDRESS,
		OID_WAN_CURRENT_ADDRESS,
		OID_WAN_MEDIUM_SUBTYPE,

		OID_WAN_CO_GET_INFO,
		OID_WAN_CO_SET_LINK_INFO,
		OID_WAN_CO_GET_LINK_INFO,

		OID_WAN_LINE_COUNT,

		OID_PNP_CAPABILITIES,
		OID_PNP_SET_POWER,
		OID_PNP_QUERY_POWER,
	};

	WCHAR _s_address_name[] = L" Address 00";
	WCHAR _s_vendor_desc[] = L"tiamo PPPoE Miniport Driver CoNdis edition for windows";
	UCHAR _s_vendor_id[4] = {0x00,0x40,0x46,0x0};
	UCHAR _s_address[ETH_ADDR_LEN] = {0x00,0x40,0x46,0x00,0x00,0x01};
}

// query request
NDIS_STATUS QueryRequest(PCHANNEL pChannel,NDIS_OID oid,PVOID pBuffer,UINT uBufferLen,PUINT puWritten,PUINT puNeeded)
{
	NDIS_STATUS status = NDIS_STATUS_SUCCESS;

	UINT uNeeded = 0;
	PVOID pTempBuffer = NULL;
	ULONG ulValue = 0;

	NDIS_CO_LINK_SPEED linkSpeed;
	NDIS_PNP_CAPABILITIES PnpCapabilities;

	switch(oid)
	{
	case OID_GEN_CO_SUPPORTED_LIST:
		pTempBuffer = _s_supported;
		uNeeded = sizeof(_s_supported);
		break;

	case OID_GEN_CO_SUPPORTED_GUIDS:
		uNeeded = 0;
		break;

	case OID_GEN_CO_HARDWARE_STATUS:
		ulValue = NdisHardwareStatusReady;
		pTempBuffer = &ulValue;
		uNeeded = sizeof(ulValue);
		break;

	case OID_GEN_CO_MEDIA_SUPPORTED:
	case OID_GEN_CO_MEDIA_IN_USE:
		ulValue = NdisMediumCoWan;
		pTempBuffer = &ulValue;
		uNeeded = sizeof(ulValue);
		break;

	case OID_GEN_CO_LINK_SPEED:
		if(pChannel)
			linkSpeed.Inbound = linkSpeed.Outbound = pChannel->m_ulLinkSpeed;
		else
			linkSpeed.Inbound = linkSpeed.Outbound = 1000000;

		pTempBuffer = &linkSpeed;
		uNeeded = sizeof(linkSpeed);
		DebugInfo(("get link speed %d,pChannel = 0x%x\n",linkSpeed.Inbound,pChannel));
		break;

	case OID_GEN_CO_VENDOR_ID:
		pTempBuffer = _s_vendor_id;
		uNeeded = sizeof(_s_vendor_id);
		break;

	case OID_GEN_CO_VENDOR_DESCRIPTION:
		pTempBuffer = _s_vendor_desc;
		uNeeded = sizeof(_s_vendor_desc);
		break;

	case OID_GEN_CO_DRIVER_VERSION:
		ulValue = (NDIS_MAJOR_VERSION << 8) | NDIS_MINOR_VERSION;
		pTempBuffer = &ulValue;
		uNeeded = sizeof(ulValue);
		break;

	case OID_GEN_CO_MAC_OPTIONS:
		ulValue = 0;
		pTempBuffer = &ulValue;
		uNeeded = sizeof(ulValue);
		break;

	case OID_GEN_CO_MEDIA_CONNECT_STATUS:
		ulValue = NdisMediaStateConnected;
		pTempBuffer = &ulValue;

⌨️ 快捷键说明

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