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

📄 asyncmac.c

📁 可用于嵌入式编程学习
💻 C
📖 第 1 页 / 共 4 页
字号:

    MiniportAdapterContext - A pointer to the adapter.


Return Value:

    The function value is the status of the operation.

--*/

{
	PASYNCMAC_ADAPTER pAdapter = (PASYNCMAC_ADAPTER)MiniportAdapterContext;
    NDIS_STATUS     StatusToReturn = NDIS_STATUS_SUCCESS;

	DEBUGMSG (ZONE_INIT|ZONE_INTERFACE,
			  (TEXT("+ASYNCMAC:MpSetInfo(0x%X, 0x%X, 0x%X, %d, 0x%X, 0x%X)\r\n"),
			   MiniportAdapterContext, Oid, InformationBuffer,
			   InformationBufferLength, BytesRead, BytesNeeded));

	ASSERT(CHK_AA(pAdapter));
	
    switch ( Oid ) {

	case OID_WAN_SET_LINK_INFO :
		if (InformationBufferLength < sizeof (NDIS_WAN_GET_LINK_INFO)) {
			StatusToReturn = NDIS_STATUS_BUFFER_TOO_SHORT;
			*BytesNeeded = sizeof(NDIS_WAN_GET_LINK_INFO);
			break;
		} else {
			PNDIS_WAN_GET_LINK_INFO	pLinkInfo = (PNDIS_WAN_GET_LINK_INFO)InformationBuffer;
			PASYNCMAC_OPEN_LINE	pOpenLine;

			pOpenLine = (PASYNCMAC_OPEN_LINE)pLinkInfo->NdisLinkHandle;
			ASSERT(CHK_AOL(pOpenLine));

			DEBUGMSG (1, (TEXT("MpSetInfo: Orig ACCM=0x%X\r\n"), pOpenLine->WanLinkInfo.SendACCM));
			
			// Let's just save this away.
			memcpy ((char *)&(pOpenLine->WanLinkInfo),
					(char *)pLinkInfo,
					sizeof (pOpenLine->WanLinkInfo));
			
			DEBUGMSG (1, (TEXT("MpSetInfo: New ACCM=0x%X\r\n"), pOpenLine->WanLinkInfo.SendACCM));
			
		}
		break;
		
	case OID_TAPI_SET_DEV_CONFIG :
		if (InformationBufferLength < sizeof(NDIS_TAPI_SET_DEV_CONFIG))
		{
			DEBUGMSG (ZONE_TAPI, (TEXT("ASYNCMAC: Buffer too short (%d < %d)\n"), InformationBufferLength, sizeof(NDIS_TAPI_SET_DEV_CONFIG)));
			StatusToReturn = NDIS_STATUS_BUFFER_TOO_SHORT;
			*BytesNeeded = sizeof(NDIS_TAPI_SET_DEV_CONFIG);
			break;
		}
		else
		{
			PNDIS_TAPI_SET_DEV_CONFIG	pTapiDevConfig = (PNDIS_TAPI_SET_DEV_CONFIG)InformationBuffer;
			LONG						lResult;

			if (pTapiDevConfig->ulDeviceConfigSize > 0)
			{
				DEBUGMSG (ZONE_TAPI, (TEXT("ASYNCMAC: Calling lineSetDevConfig\n")));
				lResult = lineSetDevConfig (
								pTapiDevConfig->ulDeviceID,
								&pTapiDevConfig->DeviceConfig[0],
								pTapiDevConfig->ulDeviceConfigSize,
								DEV_CLASS_COMM_DATAMODEM);
				if (lResult != 0)
				{
					DEBUGMSG (ZONE_TAPI|ZONE_ERROR,
							  (TEXT("lineSetDevConfig failed (%d)\n"), lResult));
					StatusToReturn = NDIS_STATUS_TAPI_INVALPARAM;
				} 
			}
		}
		break;

	case OID_TAPI_DROP :
		DEBUGMSG(ZONE_INTERFACE, (TEXT("ASYNCMAC: OID_TAPI_DROP\n")));
		if (InformationBufferLength < sizeof (NDIS_TAPI_DROP)) {
			StatusToReturn = NDIS_STATUS_BUFFER_TOO_SHORT;
			*BytesNeeded = sizeof(NDIS_TAPI_DROP);
			break;
		} else {
			PNDIS_TAPI_DROP	pTapiDrop = (PNDIS_TAPI_DROP)InformationBuffer;
			PASYNCMAC_OPEN_LINE	pOpenLine;
			long    lResult;
			
			// We return the pOpenLine for the hdCall.
			pOpenLine = (PASYNCMAC_OPEN_LINE)pTapiDrop->hdCall;
			ASSERT(CHK_AOL(pOpenLine));

			// Forward on the info.
            lResult = lineDrop(pOpenLine->hCall, pTapiDrop->UserUserInfo,
								pTapiDrop->ulUserUserInfoSize);

            DEBUGMSG( ZONE_TAPI, (TEXT("Return from lineDrop()=%d\r\n"), lResult));
			
		}
		break;

	case OID_TAPI_CLOSE_CALL :
		DEBUGMSG(ZONE_INTERFACE, (TEXT("ASYNCMAC: OID_TAPI_CLOSE_CALL\n")));
		if (InformationBufferLength < sizeof (NDIS_TAPI_CLOSE_CALL)) {
			StatusToReturn = NDIS_STATUS_BUFFER_TOO_SHORT;
			*BytesNeeded = sizeof(NDIS_TAPI_CLOSE_CALL);
			break;
		} else {
			PNDIS_TAPI_CLOSE_CALL	pTapiCloseCall = (PNDIS_TAPI_CLOSE_CALL)InformationBuffer;
			PASYNCMAC_OPEN_LINE	pOpenLine;
			long    lResult;

			// We return the pOpenLine for the hdCall.
			pOpenLine = (PASYNCMAC_OPEN_LINE)pTapiCloseCall->hdCall;
			ASSERT(CHK_AOL(pOpenLine));

			// TAPI docs state that CloseHandle must be done on the hPort before
			// calling lineDeallocateCall.
			if (pOpenLine->hPort != NULL)
			{
				CloseHandle(pOpenLine->hPort);
				pOpenLine->hPort = NULL;
			}

            lResult = lineDeallocateCall( pOpenLine->hCall );
			pOpenLine->hCall = NULL;

			// We don't actually free the pOpenLine until the OID_TAPI_CLOSE.
            DEBUGMSG( ZONE_TAPI, (TEXT("Return from lineDeallocateCall()=%d\r\n"),
								 lResult));
		}
		break;
		
	case OID_TAPI_CLOSE :
		DEBUGMSG(ZONE_INTERFACE, (TEXT("ASYNCMAC: OID_TAPI_CLOSE\n")));
		if (InformationBufferLength < sizeof (NDIS_TAPI_CLOSE)) {
			StatusToReturn = NDIS_STATUS_BUFFER_TOO_SHORT;
			*BytesNeeded = sizeof(NDIS_TAPI_CLOSE);
			break;
		} else {
			PNDIS_TAPI_CLOSE	pTapiClose = (PNDIS_TAPI_CLOSE)InformationBuffer;
			PASYNCMAC_OPEN_LINE	pOpenLine;
			long    lResult;

			// We return the pOpenLine for the hdLine.
			pOpenLine = (PASYNCMAC_OPEN_LINE)pTapiClose->hdLine;
			ASSERT(CHK_AOL(pOpenLine));

			// Ok, now it's removed from the list.
			lResult = lineClose (pOpenLine->hLine);

			ReleaseOpenLinePtr (pOpenLine);

            DEBUGMSG( ZONE_TAPI, (TEXT("Return from lineClose()=%d\r\n"), lResult));
		}
		break;

	default:

        StatusToReturn = NDIS_STATUS_INVALID_OID;

        *BytesRead   = 0;
        *BytesNeeded = 0;

        break;
    }
	DEBUGMSG (ZONE_INIT|ZONE_INTERFACE,
			  (TEXT("-ASYNCMAC:MpSetInfo: Returning 0x%X\r\n"),
			   StatusToReturn));
	
	return StatusToReturn;
}

NDIS_STATUS
MpReconfigure(
	OUT PNDIS_STATUS	OpenErrorStatus,
	IN	NDIS_HANDLE		MiniportAdapterContext,
	IN	NDIS_HANDLE		WrapperConfigurationContext
	)
{
	DEBUGMSG (ZONE_INIT|ZONE_INTERFACE,
			  (TEXT("+/-ASYNCMAC:MpReconfigure(0x%X, 0x%X, 0x%X)\r\n"),
			   OpenErrorStatus, MiniportAdapterContext,
			  WrapperConfigurationContext));
	return (NDIS_STATUS_SUCCESS);
}

NDIS_STATUS
MpReset(
	OUT PBOOLEAN		AddressingReset,
	IN	NDIS_HANDLE		MiniportAdapterContext
	)
{
	DEBUGMSG (ZONE_INIT|ZONE_INTERFACE,
			  (TEXT("+/-ASYNCMAC:MpReset(0x%X, 0x%X)\r\n"),
			   AddressingReset, MiniportAdapterContext));
    *AddressingReset = FALSE;

	return (NDIS_STATUS_SUCCESS);
}

NDIS_STATUS
MpSend(
	IN NDIS_HANDLE		MacBindingHandle,
    IN NDIS_HANDLE      NdisLinkHandle,
    IN PNDIS_WAN_PACKET pPacket)
{
	PASYNCMAC_OPEN_LINE pOpenLine = (PASYNCMAC_OPEN_LINE) NdisLinkHandle;
	NDIS_STATUS			Status = NDIS_STATUS_SUCCESS;
	DWORD				bytesWritten;		// bytes written per WriteFile call
	DWORD				packetBytesSent;	// sum of prior WriteFile bytesWritten
	
	DEBUGMSG (ZONE_INIT|ZONE_INTERFACE,
			  (TEXT("ASYNCMAC:+MpSend(0x%X, 0x%X, 0x%X)\r\n"),
			   MacBindingHandle, NdisLinkHandle,
			   pPacket));

	if (pOpenLine == NULL)
	{
		//
		//	This can happen if the connection is closed by RAS/PPP just as it is
		//	sending a packet.  In this case, we don't want to send anything.
		//
		Status = NDIS_STATUS_FAILURE;
	}
	else
	{
		ASSERT(CHK_AOL(pOpenLine));

		// Let's just send it for now.
		if (pOpenLine->hPort == NULL)
		{
			Status = NDIS_STATUS_FAILURE;
		}
		else
		{
#ifdef DEBUG
			if (ZONE_SEND)
			{
				DEBUGMSG (1, (TEXT("ASYNCMAC: MpSend: About to frame packet (%d):\n"), pPacket->CurrentLength));
				DumpMem (pPacket->CurrentBuffer, pPacket->CurrentLength);
			}
#endif
		
			if (pOpenLine->WanLinkInfo.SendFramingBits & PPP_FRAMING)
			{
				// Do CRC generation and escape byte insertion
				AssemblePPPFrame (pOpenLine, pPacket);
			}
			else
			{
				// Do SLIP escape byte insertion
				AssembleSLIPFrame(pOpenLine, pPacket);
			}

#ifdef DEBUG
			//		DEBUGMSG (1, (TEXT("MpSend: After frame packet (%d):\r\n"), pPacket->CurrentLength));
			//		DumpMem (pPacket->CurrentBuffer, pPacket->CurrentLength);
#endif

			for (packetBytesSent = 0;
				 packetBytesSent < pPacket->CurrentLength;
				 packetBytesSent += bytesWritten)
			{
				if (!WriteFile (pOpenLine->hPort, pPacket->CurrentBuffer + packetBytesSent,
								pPacket->CurrentLength - packetBytesSent, &bytesWritten, 0)
				||  bytesWritten == 0)
				{
					DEBUGMSG(ZONE_SEND | ZONE_ERROR, (
						TEXT( "AsyncMac:WriteFile Error %d Aborting Packet after sending %d of %d bytes\r\n" ),
						GetLastError(), packetBytesSent, pPacket->CurrentLength) );
						Status = NDIS_STATUS_FAILURE;
						break;
				}
				DEBUGMSG (ZONE_SEND, (TEXT("AsyncMac: MpSend wrote %d bytes\r\n"), bytesWritten));
			}
		}
	}

	DEBUGMSG ((ZONE_INIT|ZONE_INTERFACE) || (ZONE_ERROR && Status),
			  (TEXT("ASYNCMAC:-MpSend: Returning 0x%X\r\n"),
			   Status));
	
    return Status;
}

BOOL
IsValidOpenLinePtr(PASYNCMAC_OPEN_LINE pOpenLine)
//
//	Validate pOpenLine.
//	Return TRUE if it is valid, FALSE otherwise.
//
//	This function must be called with v_AdapterCS held.
{
	BOOL				bValid = FALSE;
	PASYNCMAC_OPEN_LINE pOLCurrent;

	DEBUGMSG(ZONE_FUNCTION, (TEXT("+IsValidOpenLinePtr %x\n"), pOpenLine));

	DEBUGMSG(ZONE_MISC, (TEXT(" IsValidOpenLinePtr v_pAdapter=%x\n"), v_pAdapter));
	if (v_pAdapter)
	{
		DEBUGMSG(ZONE_MISC, (TEXT(" IsValidOpenLinePtr pHead=%x\n"), v_pAdapter->pHead));
		for (pOLCurrent = v_pAdapter->pHead; pOLCurrent; pOLCurrent = pOLCurrent->pNext)
		{
			DEBUGMSG(ZONE_MISC, (TEXT(" IsValidOpenLinePtr pOLCurrent=%x\n"), pOLCurrent));
			if (pOLCurrent == pOpenLine)
			{
				bValid = TRUE;
				break;
			}
		}
	}

	DEBUGMSG(ZONE_FUNCTION, (TEXT("-IsValidOpenLinePtr %x result=%d\n"), pOpenLine, bValid));

	return bValid;
}

void
ReleaseOpenLinePtr (PASYNCMAC_OPEN_LINE pOpenLine)
//
//	Decrement the refcnt for the OpenLine parameter.
//	If the refcnt reaches zero, then no threads are using the OpenLine and so it is freed.
//
{
	PASYNCMAC_OPEN_LINE	pOLTemp;

	DEBUGMSG(ZONE_FUNCTION, (TEXT("+ReleaseOpenLinePtr %x\n"), pOpenLine));

	EnterCriticalSection(&v_AdapterCS);

	if (IsValidOpenLinePtr(pOpenLine))
	{
		pOpenLine->dwRefCnt--;
		DEBUGMSG(ZONE_MISC, (TEXT(" ReleaseOpenLinePtr refcnt now %d\n"), pOpenLine->dwRefCnt));

		if (0 == pOpenLine->dwRefCnt) {

			DEBUGMSG(ZONE_MISC, (TEXT(" ReleaseOpenLinePtr removing pOpenLine=%x\n"), pOpenLine));

			// Remove this from the adapter list.
			if (pOpenLine == pOpenLine->pAdapter->pHead) {
				// Trivial case, remove from head.
				pOpenLine->pAdapter->pHead = pOpenLine->pNext;
				DEBUGMSG(ZONE_MISC, (TEXT(" ReleaseOpenLinePtr trivial remove from head\n")));
			} else {
				for (pOLTemp = pOpenLine->pAdapter->pHead; pOLTemp; pOLTemp = pOLTemp->pNext) {
					if (pOLTemp->pNext == pOpenLine) {
						pOLTemp->pNext = pOpenLine->pNext;
						break;
					}
				}
				ASSERT (pOLTemp);
			}

			DEBUGMSG(ZONE_MISC, (TEXT("***ReleaseOpenLinePtr FREEING pOpenLine=%x\n"), pOpenLine));
			AsyncMacFreeMemory (pOpenLine, sizeof(ASYNCMAC_OPEN_LINE));
		}
	}

	LeaveCriticalSection(&v_AdapterCS);

	DEBUGMSG(ZONE_FUNCTION, (TEXT("-ReleaseOpenLinePtr %x\n"), pOpenLine));

}
PASYNCMAC_OPEN_LINE
GetOpenLinePtr (void *context)
//
//	Return an OPEN_LINE ptr if the context is valid, NULL if not.
//
//	Increments the refcnt to the OPEN_LINE.
//
//	The caller of this function must call ReleaseOpenLinePtr if this
//	function returns non-NULL, in order to decrement the refcnt.
//
{
	PASYNCMAC_OPEN_LINE	pOpenLine = (PASYNCMAC_OPEN_LINE) context;
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("+GetOpenLinePtr %x\n"), pOpenLine));

	EnterCriticalSection(&v_AdapterCS);

	if (IsValidOpenLinePtr(pOpenLine))
	{
		// Increment refcnt to make sure it doesn't go away while in use.
		pOpenLine->dwRefCnt++;
		DEBUGMSG(ZONE_FUNCTION, (TEXT(" GetOpenLinePtr refcnt now %d\n"), pOpenLine->dwRefCnt));
	}
	else
		pOpenLine = NULL;

	LeaveCriticalSection(&v_AdapterCS);

	DEBUGMSG(ZONE_FUNCTION, (TEXT("-GetOpenLinePtr result=%x\n"), pOpenLine));

	return pOpenLine;
}

⌨️ 快捷键说明

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